OSDN Git Service

Regenerate gcc/configure.
[pf3gnuchains/gcc-fork.git] / gcc / ada / prj-nmsc.adb
index 53bd367..ca6a732 100644 (file)
 
 with GNAT.Case_Util;             use GNAT.Case_Util;
 with GNAT.Directory_Operations;  use GNAT.Directory_Operations;
+with GNAT.Dynamic_HTables;
 
 with Err_Vars; use Err_Vars;
-with MLib.Tgt;
 with Opt;      use Opt;
 with Osint;    use Osint;
 with Output;   use Output;
-with Prj.Env;  use Prj.Env;
-with Prj.Err;
+with Prj.Err;  use Prj.Err;
 with Prj.Util; use Prj.Util;
 with Sinput.P;
 with Snames;   use Snames;
@@ -51,9 +50,6 @@ package body Prj.Nmsc is
    --  Used in Check_Library for continuation error messages at the same
    --  location.
 
-   ALI_Suffix   : constant String := ".ali";
-   --  File suffix for ali files
-
    type Name_Location is record
       Name     : File_Name_Type;  --  ??? duplicates the key
       Location : Source_Ptr;
@@ -80,7 +76,9 @@ package body Prj.Nmsc is
       Spec : File_Name_Type;
       Impl : File_Name_Type;
    end record;
+
    No_Unit_Exception : constant Unit_Exception := (No_Name, No_File, No_File);
+
    package Unit_Exceptions_Htable is new GNAT.Dynamic_HTables.Simple_HTable
      (Header_Num => Header_Num,
       Element    => Unit_Exception,
@@ -97,7 +95,9 @@ package body Prj.Nmsc is
       Found    : Boolean         := False;
       Location : Source_Ptr      := No_Location;
    end record;
+
    No_File_Found : constant File_Found := (No_File, False, No_Location);
+
    package Excluded_Sources_Htable is new GNAT.Dynamic_HTables.Simple_HTable
      (Header_Num => Header_Num,
       Element    => File_Found,
@@ -105,7 +105,7 @@ package body Prj.Nmsc is
       Key        => File_Name_Type,
       Hash       => Hash,
       Equal      => "=");
-   --  A hash table to store the base names of excluded files, if any.
+   --  A hash table to store the base names of excluded files, if any
 
    package Object_File_Names_Htable is new GNAT.Dynamic_HTables.Simple_HTable
      (Header_Num => Header_Num,
@@ -122,7 +122,6 @@ package body Prj.Nmsc is
       Source_Names    : Source_Names_Htable.Instance;
       Unit_Exceptions : Unit_Exceptions_Htable.Instance;
       Excluded        : Excluded_Sources_Htable.Instance;
-      Object_Files    : Object_File_Names_Htable.Instance;
 
       Source_List_File_Location : Source_Ptr;
       --  Location of the Source_List_File attribute, for error messages
@@ -131,6 +130,41 @@ package body Prj.Nmsc is
    --  information which is only useful while processing the project, and can
    --  be discarded as soon as we have finished processing the project
 
+   package Files_Htable is new GNAT.Dynamic_HTables.Simple_HTable
+     (Header_Num => Header_Num,
+      Element    => Source_Id,
+      No_Element => No_Source,
+      Key        => File_Name_Type,
+      Hash       => Hash,
+      Equal      => "=");
+   --  Mapping from base file names to Source_Id (containing full info about
+   --  the source).
+
+   type Tree_Processing_Data is record
+      Tree           : Project_Tree_Ref;
+      File_To_Source : Files_Htable.Instance;
+      Flags          : Prj.Processing_Flags;
+   end record;
+   --  Temporary data which is needed while parsing a project. It does not need
+   --  to be kept in memory once a project has been fully loaded, but is
+   --  necessary while performing consistency checks (duplicate sources,...)
+   --  This data must be initialized before processing any project, and the
+   --  same data is used for processing all projects in the tree.
+
+   procedure Initialize
+     (Data  : out Tree_Processing_Data;
+      Tree  : Project_Tree_Ref;
+      Flags : Prj.Processing_Flags);
+   --  Initialize Data
+
+   procedure Free (Data : in out Tree_Processing_Data);
+   --  Free the memory occupied by Data
+
+   procedure Check
+     (Project     : Project_Id;
+      Data        : in out Tree_Processing_Data);
+   --  Process the naming scheme for a single project
+
    procedure Initialize
      (Data    : in out Project_Processing_Data;
       Project : Project_Id);
@@ -138,8 +172,8 @@ package body Prj.Nmsc is
    --  Initialize or free memory for a project-specific data
 
    procedure Find_Excluded_Sources
-     (Project   : in out Project_Processing_Data;
-      Data      : in out Tree_Processing_Data);
+     (Project : in out Project_Processing_Data;
+      Data    : in out Tree_Processing_Data);
    --  Find the list of files that should not be considered as source files
    --  for this project. Sets the list in the Project.Excluded_Sources_Htable.
 
@@ -148,8 +182,8 @@ package body Prj.Nmsc is
    --  the unit data if necessary.
 
    procedure Load_Naming_Exceptions
-     (Project  : in out Project_Processing_Data;
-      Data     : in out Tree_Processing_Data);
+     (Project : in out Project_Processing_Data;
+      Data    : in out Tree_Processing_Data);
    --  All source files in Data.First_Source are considered as naming
    --  exceptions, and copied into the Source_Names and Unit_Exceptions tables
    --  as appropriate.
@@ -158,20 +192,25 @@ package body Prj.Nmsc is
      (Id                  : out Source_Id;
       Data                : in out Tree_Processing_Data;
       Project             : Project_Id;
+      Source_Dir_Rank     : Natural;
       Lang_Id             : Language_Ptr;
       Kind                : Source_Kind;
       File_Name           : File_Name_Type;
       Display_File        : File_Name_Type;
-      Naming_Exception    : Boolean := False;
+      Naming_Exception    : Boolean          := False;
       Path                : Path_Information := No_Path_Information;
-      Alternate_Languages : Language_List := null;
-      Unit                : Name_Id   := No_Name;
-      Index               : Int       := 0);
+      Alternate_Languages : Language_List    := null;
+      Unit                : Name_Id          := No_Name;
+      Index               : Int              := 0;
+      Locally_Removed     : Boolean          := False;
+      Location            : Source_Ptr       := No_Location);
    --  Add a new source to the different lists: list of all sources in the
    --  project tree, list of source of a project and list of sources of a
    --  language.
    --
    --  If Path is specified, the file is also added to Source_Paths_HT.
+   --
+   --  Location is used for error messages
 
    function Canonical_Case_File_Name (Name : Name_Id) return File_Name_Type;
    --  Same as Osint.Canonical_Case_File_Name but applies to Name_Id.
@@ -190,17 +229,14 @@ package body Prj.Nmsc is
    --  Copy Str into Name_Buffer, replacing Pattern with Replacement. Str is
    --  converted to lower-case at the same time.
 
-   function ALI_File_Name (Source : String) return String;
-   --  Return the ALI file name corresponding to a source
-
    procedure Check_Ada_Name (Name : String; Unit : out Name_Id);
    --  Check that a name is a valid Ada unit name
 
    procedure Check_Package_Naming
-     (Project        : Project_Id;
-      Data           : in out Tree_Processing_Data;
-      Bodies         : out Array_Element_Id;
-      Specs          : out Array_Element_Id);
+     (Project : Project_Id;
+      Data    : in out Tree_Processing_Data;
+      Bodies  : out Array_Element_Id;
+      Specs   : out Array_Element_Id);
    --  Check the naming scheme part of Data, and initialize the naming scheme
    --  data in the config of the various languages. This also returns the
    --  naming scheme exceptions for unit-based languages (Bodies and Specs are
@@ -228,8 +264,6 @@ package body Prj.Nmsc is
       Data    : in out Tree_Processing_Data);
    --  Check the library attributes of project Project in project tree
    --  and modify its data Data accordingly.
-   --  Current_Dir should represent the current directory, and is passed for
-   --  efficiency to avoid system calls to recompute it.
 
    procedure Check_Programming_Languages
      (Project : Project_Id;
@@ -238,50 +272,31 @@ package body Prj.Nmsc is
    --  tree Data.Tree and set the components of Data for all the programming
    --  languages indicated in attribute Languages, if any.
 
-   function Check_Project
-     (P            : Project_Id;
-      Root_Project : Project_Id;
-      Extending    : Boolean) return Boolean;
-   --  Returns True if P is Root_Project or, if Extending is True, a project
-   --  extended by Root_Project.
-
    procedure Check_Stand_Alone_Library
-     (Project     : Project_Id;
-      Current_Dir : String;
-      Extending   : Boolean;
-      Data        : in out Tree_Processing_Data);
+     (Project : Project_Id;
+      Data    : in out Tree_Processing_Data);
    --  Check if project Project in project tree Data.Tree is a Stand-Alone
    --  Library project, and modify its data Data accordingly if it is one.
-   --  Current_Dir should represent the current directory, and is passed for
-   --  efficiency to avoid system calls to recompute it.
 
    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.
 
-   procedure Error_Msg
-     (Project       : Project_Id;
-      Msg           : String;
-      Flag_Location : Source_Ptr;
-      Data          : Tree_Processing_Data);
-   --  Output an error message. If Data.Error_Report is null, simply call
-   --  Prj.Err.Error_Msg. Otherwise, disregard Flag_Location and use
-   --  Error_Report.
-
    procedure Search_Directories
      (Project         : in out Project_Processing_Data;
       Data            : in out Tree_Processing_Data;
       For_All_Sources : Boolean);
    --  Search the source directories to find the sources. If For_All_Sources is
    --  True, check each regular file name against the naming schemes of the
-   --  different languages. Otherwise consider only the file names in the hash
-   --  table Source_Names. If Allow_Duplicate_Basenames, then files with the
-   --  same base names are authorized within a project for source-based
-   --  languages (never for unit based languages)
+   --  various languages. Otherwise consider only the file names in hash table
+   --  Source_Names. If Allow_Duplicate_Basenames then files with identical
+   --  base names are permitted within a project for source-based languages
+   --  (never for unit based languages).
 
    procedure Check_File
      (Project           : in out Project_Processing_Data;
       Data              : in out Tree_Processing_Data;
+      Source_Dir_Rank   : Natural;
       Path              : Path_Name_Type;
       File_Name         : File_Name_Type;
       Display_File_Name : File_Name_Type;
@@ -298,13 +313,12 @@ package body Prj.Nmsc is
    --  File_Name is the same as Name, but has been normalized.
    --  Display_File_Name, however, has not been normalized.
    --
-   --  Source_Directory is the directory in which the file
-   --  was found. It hasn't been normalized (nor has had links resolved).
-   --  It should not end with a directory separator, to avoid duplicates
-   --  later on.
+   --  Source_Directory is the directory in which the file was found. It is
+   --  neither normalized nor has had links resolved, and must not end with a
+   --  a directory separator, to avoid duplicates later on.
    --
    --  If For_All_Sources is True, then all possible file names are analyzed
-   --  otherwise only those currently set in the Source_Names htable.
+   --  otherwise only those currently set in the Source_Names hash table.
 
    procedure Check_File_Naming_Schemes
      (In_Tree               : Project_Tree_Ref;
@@ -324,11 +338,9 @@ package body Prj.Nmsc is
 
    procedure Get_Directories
      (Project     : Project_Id;
-      Current_Dir : String;
       Data        : in out Tree_Processing_Data);
    --  Get the object directory, the exec directory and the source directories
-   --  of a project. Current_Dir should represent the current directory, and is
-   --  passed for efficiency to avoid system calls to recompute it.
+   --  of a project.
 
    procedure Get_Mains
      (Project : Project_Id;
@@ -337,16 +349,16 @@ package body Prj.Nmsc is
    --  them in the project data.
 
    procedure Get_Sources_From_File
-     (Path      : String;
-      Location  : Source_Ptr;
-      Project   : in out Project_Processing_Data;
-      Data      : in out Tree_Processing_Data);
+     (Path     : String;
+      Location : Source_Ptr;
+      Project  : in out Project_Processing_Data;
+      Data     : in out Tree_Processing_Data);
    --  Get the list of sources from a text file and put them in hash table
    --  Source_Names.
 
    procedure Find_Sources
-     (Project   : in out Project_Processing_Data;
-      Data      : in out Tree_Processing_Data);
+     (Project : in out Project_Processing_Data;
+      Data    : in out Tree_Processing_Data);
    --  Process the Source_Files and Source_List_File attributes, and store the
    --  list of source files into the Source_Names htable. When these attributes
    --  are not defined, find all files matching the naming schemes in the
@@ -395,8 +407,7 @@ package body Prj.Nmsc is
    --  returned), or simply returned without checking for its existence (if
    --  Must_Exist is False) or No_Path_Information is returned. In all cases,
    --  Dir_Exists indicates whether the directory now exists. Create is also
-   --  used for debugging traces to show which path we are
-   --  computing
+   --  used for debugging traces to show which path we are computing.
 
    procedure Look_For_Sources
      (Project : in out Project_Processing_Data;
@@ -415,10 +426,10 @@ package body Prj.Nmsc is
    procedure Remove_Source
      (Id          : Source_Id;
       Replaced_By : Source_Id);
-   --  Remove a file from the list of sources of a project.
-   --  This might be because the file is replaced by another one in an
-   --  extending project, or because a file was added as a naming exception
-   --  but was not found in the end.
+   --  Remove a file from the list of sources of a project. This might be
+   --  because the file is replaced by another one in an extending project,
+   --  or because a file was added as a naming exception but was not found
+   --  in the end.
 
    procedure Report_No_Sources
      (Project      : Project_Id;
@@ -485,9 +496,13 @@ package body Prj.Nmsc is
       end if;
 
       declare
-         Suf : constant String := Get_Name_String (Suffix);
+         Suf : String := Get_Name_String (Suffix);
 
       begin
+         --  On non case-sensitive systems, use proper suffix casing
+
+         Canonical_Case_File_Name (Suf);
+
          --  The file name must end with the suffix (which is not an extension)
          --  For instance a suffix "configure.in" must match a file with the
          --  same name. To avoid dummy cases, though, a suffix starting with
@@ -526,134 +541,152 @@ package body Prj.Nmsc is
      (Id                  : out Source_Id;
       Data                : in out Tree_Processing_Data;
       Project             : Project_Id;
+      Source_Dir_Rank     : Natural;
       Lang_Id             : Language_Ptr;
       Kind                : Source_Kind;
       File_Name           : File_Name_Type;
       Display_File        : File_Name_Type;
-      Naming_Exception    : Boolean := False;
+      Naming_Exception    : Boolean          := False;
       Path                : Path_Information := No_Path_Information;
-      Alternate_Languages : Language_List := null;
-      Unit                : Name_Id   := No_Name;
-      Index               : Int       := 0)
+      Alternate_Languages : Language_List    := null;
+      Unit                : Name_Id          := No_Name;
+      Index               : Int              := 0;
+      Locally_Removed     : Boolean          := False;
+      Location            : Source_Ptr       := No_Location)
    is
       Config    : constant Language_Config := Lang_Id.Config;
       UData     : Unit_Index;
       Add_Src   : Boolean;
       Source    : Source_Id;
       Prev_Unit : Unit_Index := No_Unit_Index;
+
       Source_To_Replace : Source_Id := No_Source;
 
    begin
       --  Check if the same file name or unit is used in the prj tree
 
       Add_Src := True;
-      Source  := Files_Htable.Get (Data.File_To_Source, File_Name);
 
       if Unit /= No_Name then
          Prev_Unit := Units_Htable.Get (Data.Tree.Units_HT, Unit);
       end if;
 
       if Prev_Unit /= No_Unit_Index
-        and then (Kind = Impl or Kind = Spec)
+        and then (Kind = Impl or else Kind = Spec)
         and then Prev_Unit.File_Names (Kind) /= null
       then
          --  Suspicious, we need to check later whether this is authorized
+
          Add_Src := False;
          Source := Prev_Unit.File_Names (Kind);
 
-      elsif Source /= No_Source then
-         if Source.Index = Index then
+      else
+         Source  := Files_Htable.Get (Data.File_To_Source, File_Name);
+
+         if Source /= No_Source
+           and then Source.Index = Index
+         then
             Add_Src := False;
          end if;
       end if;
 
-      --  Duplication of file/unit in same project is allowed
-      --  if order of source directories is known.
+      --  Duplication of file/unit in same project is allowed if order of
+      --  source directories is known.
 
       if Add_Src = False then
          Add_Src := True;
 
          if Project = Source.Project then
             if Prev_Unit = No_Unit_Index then
-               if Data.Allow_Duplicate_Basenames then
+               if Data.Flags.Allow_Duplicate_Basenames then
                   Add_Src := True;
-               elsif Project.Known_Order_Of_Source_Dirs then
+
+               elsif Source_Dir_Rank /= Source.Source_Dir_Rank then
                   Add_Src := False;
+
                else
                   Error_Msg_File_1 := File_Name;
                   Error_Msg
-                    (Project, "duplicate source file name {",
-                     No_Location, Data);
+                    (Data.Flags, "duplicate source file name {",
+                     Location, Project);
                   Add_Src := False;
                end if;
 
             else
-               if Project.Known_Order_Of_Source_Dirs then
+               if Source_Dir_Rank /= Source.Source_Dir_Rank then
                   Add_Src := False;
 
                --  We might be seeing the same file through a different path
-               --  (for instance because of symbolic links)
+               --  (for instance because of symbolic links).
 
                elsif Source.Path.Name /= Path.Name then
                   Error_Msg_Name_1 := Unit;
                   Error_Msg
-                    (Project, "duplicate unit %%", No_Location, Data);
+                    (Data.Flags, "duplicate unit %%", Location, Project);
                   Add_Src := False;
                end if;
             end if;
 
-            --  Do not allow the same unit name in different projects,
-            --  except if one is extending the other.
+            --  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.
+            --  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) then
-            Source_To_Replace := Source;
+            if not Locally_Removed then
+               Source_To_Replace := Source;
+            end if;
 
          elsif Prev_Unit /= No_Unit_Index
            and then not Source.Locally_Removed
          then
+            --  Path is set if this is a source we found on the disk, in which
+            --  case we can provide more explicit error message. Path is unset
+            --  when the source is added from one of the naming exceptions in
+            --  the project.
+
             if Path /= No_Path_Information then
                Error_Msg_Name_1 := Unit;
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "unit %% cannot belong to several projects",
-                  No_Location, Data);
+                  Location, Project);
 
                Error_Msg_Name_1 := Project.Name;
-               Error_Msg_Name_2 := Name_Id (Path.Name);
+               Error_Msg_Name_2 := Name_Id (Path.Display_Name);
                Error_Msg
-                 (Project, "\  project %%, %%", No_Location, Data);
+                 (Data.Flags, "\  project %%, %%", Location, Project);
 
                Error_Msg_Name_1 := Source.Project.Name;
                Error_Msg_Name_2 := Name_Id (Source.Path.Display_Name);
                Error_Msg
-                 (Project, "\  project %%, %%", No_Location, Data);
+                 (Data.Flags, "\  project %%, %%", Location, Project);
 
             else
                Error_Msg_Name_1 := Unit;
                Error_Msg_Name_2 := Source.Project.Name;
                Error_Msg
-                 (Project, "unit %% already belongs to project %%",
-                  No_Location, Data);
+                 (Data.Flags, "unit %% already belongs to project %%",
+                  Location, Project);
             end if;
 
             Add_Src := False;
 
          elsif not Source.Locally_Removed
-           and then not Data.Allow_Duplicate_Basenames
+           and then not Data.Flags.Allow_Duplicate_Basenames
            and then Lang_Id.Config.Kind = Unit_Based
          then
             Error_Msg_File_1 := File_Name;
             Error_Msg_File_2 := File_Name_Type (Source.Project.Name);
             Error_Msg
-              (Project,
-               "{ is already a source of project {", No_Location, Data);
+              (Data.Flags,
+               "{ is already a source of project {", Location, Project);
 
             --  Add the file anyway, to avoid further warnings like "language
-            --  unknown"
+            --  unknown".
+
             Add_Src := True;
          end if;
       end if;
@@ -692,19 +725,32 @@ package body Prj.Nmsc is
       end if;
 
       Id.Project             := Project;
+      Id.Source_Dir_Rank     := Source_Dir_Rank;
       Id.Language            := Lang_Id;
       Id.Kind                := Kind;
       Id.Alternate_Languages := Alternate_Languages;
+      Id.Locally_Removed     := Locally_Removed;
+      Id.Index               := Index;
+      Id.File                := File_Name;
+      Id.Display_File        := Display_File;
+      Id.Dep_Name            := Dependency_Name
+                                  (File_Name, Lang_Id.Config.Dependency_Kind);
+      Id.Naming_Exception    := Naming_Exception;
 
       --  Add the source id to the Unit_Sources_HT hash table, if the unit name
       --  is not null.
 
       if Unit /= No_Name then
-         Unit_Sources_Htable.Set (Data.Tree.Unit_Sources_HT, Unit, Id);
 
-         --  ??? Record_Unit has already fetched that earlier, so this isn't
-         --  the most efficient way. But we can't really pass a parameter since
-         --  Process_Exceptions_Unit_Based and Check_File haven't looked it up.
+         --  Note: we might be creating a dummy unit here, when we in fact have
+         --  a separate. For instance, file file-bar.adb will initially be
+         --  assumed to be the IMPL of unit "file.bar". Only later on (in
+         --  Check_Object_Files) will we parse those units that only have an
+         --  impl and no spec to make sure whether we have a Separate in fact
+         --  (that significantly reduces the number of times we need to parse
+         --  the files, since we are then only interested in those with no
+         --  spec). We still need those dummy units in the table, since that's
+         --  the name we find in the ALI file
 
          UData := Units_Htable.Get (Data.Tree.Units_HT, Unit);
 
@@ -721,13 +767,6 @@ package body Prj.Nmsc is
          Override_Kind (Id, Kind);
       end if;
 
-      Id.Index            := Index;
-      Id.File             := File_Name;
-      Id.Display_File     := Display_File;
-      Id.Dep_Name         := Dependency_Name
-                               (File_Name, Lang_Id.Config.Dependency_Kind);
-      Id.Naming_Exception := Naming_Exception;
-
       if Is_Compilable (Id) and then Config.Object_Generated then
          Id.Object   := Object_Name (File_Name, Config.Object_File_Suffix);
          Id.Switches := Switches_Name (File_Name);
@@ -738,6 +777,10 @@ package body Prj.Nmsc is
          Source_Paths_Htable.Set (Data.Tree.Source_Paths_HT, Path.Name, Id);
       end if;
 
+      if Index /= 0 then
+         Project.Has_Multi_Unit_Sources := True;
+      end if;
+
       --  Add the source to the language list
 
       Id.Next_In_Lang := Lang_Id.First_Source;
@@ -750,25 +793,6 @@ package body Prj.Nmsc is
       Files_Htable.Set (Data.File_To_Source, File_Name, Id);
    end Add_Source;
 
-   -------------------
-   -- ALI_File_Name --
-   -------------------
-
-   function ALI_File_Name (Source : String) return String is
-   begin
-      --  If the source name has extension, replace it with the ALI suffix
-
-      for Index in reverse Source'First + 1 .. Source'Last loop
-         if Source (Index) = '.' then
-            return Source (Source'First .. Index - 1) & ALI_Suffix;
-         end if;
-      end loop;
-
-      --  If no dot, or if it is the first character, just add the ALI suffix
-
-      return Source & ALI_Suffix;
-   end ALI_File_Name;
-
    ------------------------------
    -- Canonical_Case_File_Name --
    ------------------------------
@@ -789,9 +813,8 @@ package body Prj.Nmsc is
    -----------
 
    procedure Check
-     (Project        : Project_Id;
-      Current_Dir    : String;
-      Data           : in out Tree_Processing_Data)
+     (Project     : Project_Id;
+      Data        : in out Tree_Processing_Data)
    is
       Specs     : Array_Element_Id;
       Bodies    : Array_Element_Id;
@@ -805,7 +828,7 @@ package body Prj.Nmsc is
 
       --  Object, exec and source directories
 
-      Get_Directories (Project, Current_Dir, Data);
+      Get_Directories (Project, Data);
 
       --  Get the programming languages
 
@@ -842,19 +865,19 @@ package body Prj.Nmsc is
 
             else
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "at least one of Source_Files, Source_Dirs or Languages "
                     & "must be declared empty for an abstract project",
-                  Project.Location, Data);
+                  Project.Location, Project);
             end if;
          end;
       end if;
 
-      --  Check configuration in multi language mode
+      --  Check configuration. This must be done even for gnatmake (even though
+      --  no user configuration file was provided) since the default config we
+      --  generate indicates whether libraries are supported for instance.
 
-      if Must_Check_Configuration then
-         Check_Configuration (Project, Data);
-      end if;
+      Check_Configuration (Project, Data);
 
       --  Library attributes
 
@@ -891,9 +914,8 @@ package body Prj.Nmsc is
                   --  are sources for which this is an alternate language.
 
                   if Language.First_Source = No_Source
-                    and then
-                      (Data.Require_Sources_Other_Lang
-                       or else Language.Name = Name_Ada)
+                    and then (Data.Flags.Require_Sources_Other_Lang
+                               or else Language.Name = Name_Ada)
                   then
                      Iter := For_Each_Source (In_Tree => Data.Tree,
                                               Project => Project);
@@ -912,6 +934,7 @@ package body Prj.Nmsc is
                      end loop Source_Loop;
 
                      if Source = No_Source then
+
                         Report_No_Sources
                           (Project,
                            Get_Name_String (Language.Display_Name),
@@ -928,18 +951,15 @@ package body Prj.Nmsc is
          end if;
       end if;
 
-      if Get_Mode = Multi_Language then
+      --  If a list of sources is specified in attribute Interfaces, set
+      --  In_Interfaces only for the sources specified in the list.
 
-         --  If a list of sources is specified in attribute Interfaces, set
-         --  In_Interfaces only for the sources specified in the list.
-
-         Check_Interfaces (Project, Data);
-      end if;
+      Check_Interfaces (Project, Data);
 
       --  If it is a library project file, check if it is a standalone library
 
       if Project.Library then
-         Check_Stand_Alone_Library (Project, Current_Dir, Extending, Data);
+         Check_Stand_Alone_Library (Project, Data);
       end if;
 
       --  Put the list of Mains, if any, in the project data
@@ -1371,8 +1391,8 @@ package body Prj.Nmsc is
 
                            if List = Nil_String then
                               Error_Msg
-                                (Project, "include option cannot be null",
-                                 Element.Value.Location, Data);
+                                (Data.Flags, "include option cannot be null",
+                                 Element.Value.Location, Project);
                            end if;
 
                            Put (Into_List => Lang_Index.Config.Include_Option,
@@ -1415,6 +1435,34 @@ package body Prj.Nmsc is
                                 From_List => Element.Value.Values,
                                 In_Tree   => Data.Tree);
 
+                        when Name_Multi_Unit_Switches =>
+                           Put (Into_List =>
+                                  Lang_Index.Config.Multi_Unit_Switches,
+                                From_List => Element.Value.Values,
+                                In_Tree   => Data.Tree);
+
+                        when Name_Multi_Unit_Object_Separator =>
+                           Get_Name_String (Element.Value.Value);
+
+                           if Name_Len /= 1 then
+                              Error_Msg
+                                (Data.Flags,
+                                 "multi-unit object separator must have " &
+                                 "a single character",
+                                 Element.Value.Location, Project);
+
+                           elsif Name_Buffer (1) = ' ' then
+                              Error_Msg
+                                (Data.Flags,
+                                 "multi-unit object separator cannot be " &
+                                 "a space",
+                                 Element.Value.Location, Project);
+
+                           else
+                              Lang_Index.Config.Multi_Unit_Object_Separator :=
+                                Name_Buffer (1);
+                           end if;
+
                         when Name_Path_Syntax =>
                            begin
                               Lang_Index.Config.Path_Syntax :=
@@ -1424,15 +1472,17 @@ package body Prj.Nmsc is
                            exception
                               when Constraint_Error =>
                                  Error_Msg
-                                   (Project, "invalid value for Path_Syntax",
-                                    Element.Value.Location, Data);
+                                   (Data.Flags,
+                                    "invalid value for Path_Syntax",
+                                    Element.Value.Location, Project);
                            end;
 
                         when Name_Object_File_Suffix =>
                            if Get_Name_String (Element.Value.Value) = "" then
                               Error_Msg
-                                (Project, "object file suffix cannot be empty",
-                                 Element.Value.Location, Data);
+                                (Data.Flags,
+                                 "object file suffix cannot be empty",
+                                 Element.Value.Location, Project);
 
                            else
                               Lang_Index.Config.Object_File_Suffix :=
@@ -1453,8 +1503,9 @@ package body Prj.Nmsc is
 
                            if List = Nil_String then
                               Error_Msg
-                                (Project, "compiler PIC option cannot be null",
-                                 Element.Value.Location, Data);
+                                (Data.Flags,
+                                 "compiler PIC option cannot be null",
+                                 Element.Value.Location, Project);
                            end if;
 
                            Put (Into_List =>
@@ -1470,9 +1521,9 @@ package body Prj.Nmsc is
 
                            if List = Nil_String then
                               Error_Msg
-                                (Project,
+                                (Data.Flags,
                                  "mapping file switches cannot be null",
-                                 Element.Value.Location, Data);
+                                 Element.Value.Location, Project);
                            end if;
 
                            Put (Into_List =>
@@ -1502,9 +1553,9 @@ package body Prj.Nmsc is
 
                            if List = Nil_String then
                               Error_Msg
-                                (Project,
+                                (Data.Flags,
                                  "config file switches cannot be null",
-                                 Element.Value.Location, Data);
+                                 Element.Value.Location, Project);
                            end if;
 
                            Put (Into_List =>
@@ -1533,10 +1584,18 @@ package body Prj.Nmsc is
                            Lang_Index.Config.Config_Body :=
                              Element.Value.Value;
 
+                        when Name_Config_Body_File_Name_Index =>
+
+                           --  Attribute Config_Body_File_Name_Index
+                           --     ( < Language > )
+
+                           Lang_Index.Config.Config_Body_Index :=
+                             Element.Value.Value;
+
                         when Name_Config_Body_File_Name_Pattern =>
 
                            --  Attribute Config_Body_File_Name_Pattern
-                           --  (<language>)
+                           --    (<language>)
 
                            Lang_Index.Config.Config_Body_Pattern :=
                              Element.Value.Value;
@@ -1548,10 +1607,18 @@ package body Prj.Nmsc is
                            Lang_Index.Config.Config_Spec :=
                              Element.Value.Value;
 
+                        when Name_Config_Spec_File_Name_Index =>
+
+                           --  Attribute Config_Spec_File_Name_Index
+                           --    ( < Language > )
+
+                           Lang_Index.Config.Config_Spec_Index :=
+                             Element.Value.Value;
+
                         when Name_Config_Spec_File_Name_Pattern =>
 
                            --  Attribute Config_Spec_File_Name_Pattern
-                           --  (<language>)
+                           --    (<language>)
 
                            Lang_Index.Config.Config_Spec_Pattern :=
                              Element.Value.Value;
@@ -1567,9 +1634,9 @@ package body Prj.Nmsc is
                            exception
                               when Constraint_Error =>
                                  Error_Msg
-                                   (Project,
+                                   (Data.Flags,
                                     "illegal value for Config_File_Unique",
-                                    Element.Value.Location, Data);
+                                    Element.Value.Location, Project);
                            end;
 
                         when others =>
@@ -1620,9 +1687,9 @@ package body Prj.Nmsc is
                      exception
                         when Constraint_Error =>
                            Error_Msg
-                             (Project,
+                             (Data.Flags,
                               "invalid value for Casing",
-                              Attribute.Value.Location, Data);
+                              Attribute.Value.Location, Project);
                      end;
 
                   elsif Attribute.Name = Name_Dot_Replacement then
@@ -1751,9 +1818,9 @@ package body Prj.Nmsc is
                      exception
                         when Constraint_Error =>
                            Error_Msg
-                             (Project,
+                             (Data.Flags,
                               "value must be positive or equal to 0",
-                              Attribute.Value.Location, Data);
+                              Attribute.Value.Location, Project);
                      end;
 
                   elsif Attribute.Name = Name_Response_File_Format then
@@ -1779,9 +1846,9 @@ package body Prj.Nmsc is
 
                         else
                            Error_Msg
-                             (Project,
+                             (Data.Flags,
                               "illegal response file format",
-                              Attribute.Value.Location, Data);
+                              Attribute.Value.Location, Project);
                         end if;
                      end;
 
@@ -1884,9 +1951,9 @@ package body Prj.Nmsc is
 
                   if List = Nil_String then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "archive builder cannot be null",
-                        Attribute.Value.Location, Data);
+                        Attribute.Value.Location, Project);
                   end if;
 
                   Put (Into_List => Project.Config.Archive_Builder,
@@ -1918,9 +1985,9 @@ package body Prj.Nmsc is
 
                   if List = Nil_String then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "archive indexer cannot be null",
-                        Attribute.Value.Location, Data);
+                        Attribute.Value.Location, Project);
                   end if;
 
                   Put (Into_List => Project.Config.Archive_Indexer,
@@ -1937,9 +2004,9 @@ package body Prj.Nmsc is
 
                   if List = Nil_String then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "partial linker cannot be null",
-                        Attribute.Value.Location, Data);
+                        Attribute.Value.Location, Project);
                   end if;
 
                   Put (Into_List => Project.Config.Lib_Partial_Linker,
@@ -1950,10 +2017,10 @@ package body Prj.Nmsc is
                   Project.Config.Shared_Lib_Driver :=
                     File_Name_Type (Attribute.Value.Value);
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "?Library_'G'C'C is an obsolescent attribute, " &
                      "use Linker''Driver instead",
-                     Attribute.Value.Location, Data);
+                     Attribute.Value.Location, Project);
 
                elsif Attribute.Name = Name_Archive_Suffix then
                   Project.Config.Archive_Suffix :=
@@ -1968,9 +2035,9 @@ package body Prj.Nmsc is
 
                   if List = Nil_String then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "linker executable option cannot be null",
-                        Attribute.Value.Location, Data);
+                        Attribute.Value.Location, Project);
                   end if;
 
                   Put (Into_List => Project.Config.Linker_Executable_Option,
@@ -1987,9 +2054,9 @@ package body Prj.Nmsc is
 
                   if Name_Len = 0 then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "linker library directory option cannot be empty",
-                        Attribute.Value.Location, Data);
+                        Attribute.Value.Location, Project);
                   end if;
 
                   Project.Config.Linker_Lib_Dir_Option :=
@@ -2005,9 +2072,9 @@ package body Prj.Nmsc is
 
                   if Name_Len = 0 then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "linker library name option cannot be empty",
-                        Attribute.Value.Location, Data);
+                        Attribute.Value.Location, Project);
                   end if;
 
                   Project.Config.Linker_Lib_Name_Option :=
@@ -2026,6 +2093,22 @@ package body Prj.Nmsc is
                           In_Tree   => Data.Tree);
                   end if;
 
+               elsif Attribute.Name = Name_Run_Path_Origin then
+                  Get_Name_String (Attribute.Value.Value);
+
+                  if Name_Len = 0 then
+                     Error_Msg
+                       (Data.Flags,
+                        "run path origin cannot be empty",
+                        Attribute.Value.Location, Project);
+                  end if;
+
+                  Project.Config.Run_Path_Origin := Attribute.Value.Value;
+
+               elsif Attribute.Name = Name_Library_Install_Name_Option then
+                  Project.Config.Library_Install_Name_Option :=
+                    Attribute.Value.Value;
+
                elsif Attribute.Name = Name_Separate_Run_Path_Options then
                   declare
                      pragma Unsuppress (All_Checks);
@@ -2035,11 +2118,11 @@ package body Prj.Nmsc is
                   exception
                      when Constraint_Error =>
                         Error_Msg
-                          (Project,
+                          (Data.Flags,
                            "invalid value """ &
                            Get_Name_String (Attribute.Value.Value) &
                            """ for Separate_Run_Path_Options",
-                           Attribute.Value.Location, Data);
+                           Attribute.Value.Location, Project);
                   end;
 
                elsif Attribute.Name = Name_Library_Support then
@@ -2052,11 +2135,11 @@ package body Prj.Nmsc is
                   exception
                      when Constraint_Error =>
                         Error_Msg
-                          (Project,
+                          (Data.Flags,
                            "invalid value """ &
                            Get_Name_String (Attribute.Value.Value) &
                            """ for Library_Support",
-                           Attribute.Value.Location, Data);
+                           Attribute.Value.Location, Project);
                   end;
 
                elsif Attribute.Name = Name_Shared_Library_Prefix then
@@ -2077,11 +2160,11 @@ package body Prj.Nmsc is
                   exception
                      when Constraint_Error =>
                         Error_Msg
-                          (Project,
+                          (Data.Flags,
                            "invalid value """
                              & Get_Name_String (Attribute.Value.Value)
                              & """ for Symbolic_Link_Supported",
-                           Attribute.Value.Location, Data);
+                           Attribute.Value.Location, Project);
                   end;
 
                elsif
@@ -2096,11 +2179,11 @@ package body Prj.Nmsc is
                   exception
                      when Constraint_Error =>
                         Error_Msg
-                          (Project,
+                          (Data.Flags,
                            "invalid value """ &
                            Get_Name_String (Attribute.Value.Value) &
                            """ for Library_Major_Minor_Id_Supported",
-                           Attribute.Value.Location, Data);
+                           Attribute.Value.Location, Project);
                   end;
 
                elsif Attribute.Name = Name_Library_Auto_Init_Supported then
@@ -2112,11 +2195,11 @@ package body Prj.Nmsc is
                   exception
                      when Constraint_Error =>
                         Error_Msg
-                          (Project,
+                          (Data.Flags,
                            "invalid value """
                              & Get_Name_String (Attribute.Value.Value)
                              & """ for Library_Auto_Init_Supported",
-                           Attribute.Value.Location, Data);
+                           Attribute.Value.Location, Project);
                   end;
 
                elsif Attribute.Name = Name_Shared_Library_Minimum_Switches then
@@ -2235,11 +2318,11 @@ package body Prj.Nmsc is
                         exception
                            when Constraint_Error =>
                               Error_Msg
-                                (Project,
+                                (Data.Flags,
                                  "invalid value """
                                  & Get_Name_String (Element.Value.Value)
                                  & """ for Object_Generated",
-                                 Element.Value.Location, Data);
+                                 Element.Value.Location, Project);
                         end;
 
                      when Name_Objects_Linked =>
@@ -2262,11 +2345,11 @@ package body Prj.Nmsc is
                         exception
                            when Constraint_Error =>
                               Error_Msg
-                                (Project,
+                                (Data.Flags,
                                  "invalid value """
                                  & Get_Name_String (Element.Value.Value)
                                  & """ for Objects_Linked",
-                                 Element.Value.Location, Data);
+                                 Element.Value.Location, Project);
                         end;
                      when others =>
                         null;
@@ -2328,15 +2411,15 @@ package body Prj.Nmsc is
          --  For all languages, Compiler_Driver needs to be specified. This is
          --  only needed if we do intend to compile (not in GPS for instance).
 
-         if Data.Compiler_Driver_Mandatory
+         if Data.Flags.Compiler_Driver_Mandatory
            and then Lang_Index.Config.Compiler_Driver = No_File
          then
             Error_Msg_Name_1 := Lang_Index.Display_Name;
             Error_Msg
-              (Project,
+              (Data.Flags,
                "?no compiler specified for language %%" &
                  ", ignoring all its sources",
-               No_Location, Data);
+               No_Location, Project);
 
             if Lang_Index = Project.Languages then
                Project.Languages := Lang_Index.Next;
@@ -2352,23 +2435,23 @@ package body Prj.Nmsc is
 
             if Lang_Index.Config.Naming_Data.Dot_Replacement = No_File then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "Dot_Replacement not specified for Ada",
-                  No_Location, Data);
+                  No_Location, Project);
             end if;
 
             if Lang_Index.Config.Naming_Data.Spec_Suffix = No_File then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "Spec_Suffix not specified for Ada",
-                  No_Location, Data);
+                  No_Location, Project);
             end if;
 
             if Lang_Index.Config.Naming_Data.Body_Suffix = No_File then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "Body_Suffix not specified for Ada",
-                  No_Location, Data);
+                  No_Location, Project);
             end if;
 
          else
@@ -2377,14 +2460,15 @@ package body Prj.Nmsc is
             --  For file based languages, either Spec_Suffix or Body_Suffix
             --  need to be specified.
 
-            if Lang_Index.Config.Naming_Data.Spec_Suffix = No_File and then
-              Lang_Index.Config.Naming_Data.Body_Suffix = No_File
+            if Data.Flags.Require_Sources_Other_Lang
+              and then 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 := Lang_Index.Display_Name;
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "no suffixes specified for %%",
-                  No_Location, Data);
+                  No_Location, Project);
             end if;
          end if;
 
@@ -2414,9 +2498,9 @@ package body Prj.Nmsc is
             Project.Externally_Built := True;
 
          elsif Name_Buffer (1 .. Name_Len) /= "false" then
-            Error_Msg (Project,
+            Error_Msg (Data.Flags,
                        "Externally_Built may only be true or false",
-                       Externally_Built.Location, Data);
+                       Externally_Built.Location, Project);
          end if;
       end if;
 
@@ -2452,6 +2536,12 @@ package body Prj.Nmsc is
                         Project.Decl.Attributes,
                         Data.Tree);
 
+      Library_Interface : constant Prj.Variable_Value :=
+                            Prj.Util.Value_Of
+                              (Snames.Name_Library_Interface,
+                               Project.Decl.Attributes,
+                               Data.Tree);
+
       List      : String_List_Id;
       Element   : String_Element;
       Name      : File_Name_Type;
@@ -2525,10 +2615,10 @@ package body Prj.Nmsc is
                Error_Msg_Name_1 := Project.Name;
 
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "{ cannot be an interface of project %% "
                   & "as it is not one of its sources",
-                  Element.Location, Data);
+                  Element.Location, Project);
             end if;
 
             List := Element.Next;
@@ -2536,22 +2626,90 @@ package body Prj.Nmsc is
 
          Project.Interfaces_Defined := True;
 
-      elsif Project.Extends /= No_Project then
-         Project.Interfaces_Defined := Project.Extends.Interfaces_Defined;
+      elsif Project.Library and then not Library_Interface.Default then
+
+         --  Set In_Interfaces to False for all sources. It will be set to True
+         --  later for the sources in the Library_Interface list.
 
-         if Project.Interfaces_Defined then
-            Iter := For_Each_Source (Data.Tree, Project);
+         Project_2 := Project;
+         while Project_2 /= No_Project loop
+            Iter := For_Each_Source (Data.Tree, Project_2);
             loop
                Source := Prj.Element (Iter);
                exit when Source = No_Source;
-
-               if not Source.Declared_In_Interfaces then
-                  Source.In_Interfaces := False;
-               end if;
-
+               Source.In_Interfaces := False;
                Next (Iter);
             end loop;
-         end if;
+
+            Project_2 := Project_2.Extends;
+         end loop;
+
+         List := Library_Interface.Values;
+         while List /= Nil_String loop
+            Element := Data.Tree.String_Elements.Table (List);
+            Get_Name_String (Element.Value);
+            To_Lower (Name_Buffer (1 .. Name_Len));
+            Name := Name_Find;
+
+            Project_2 := Project;
+            Big_Loop_2 :
+            while Project_2 /= No_Project loop
+               Iter := For_Each_Source (Data.Tree, Project_2);
+
+               loop
+                  Source := Prj.Element (Iter);
+                  exit when Source = No_Source;
+
+                  if Source.Unit /= No_Unit_Index and then
+                     Source.Unit.Name = Name_Id (Name)
+                  then
+                     if not Source.Locally_Removed then
+                        Source.In_Interfaces := True;
+                        Source.Declared_In_Interfaces := True;
+
+                        Other := Other_Part (Source);
+
+                        if Other /= No_Source then
+                           Other.In_Interfaces := True;
+                           Other.Declared_In_Interfaces := True;
+                        end if;
+
+                        if Current_Verbosity = High then
+                           Write_Str ("   interface: ");
+                           Write_Line (Get_Name_String (Source.Path.Name));
+                        end if;
+                     end if;
+
+                     exit Big_Loop_2;
+                  end if;
+
+                  Next (Iter);
+               end loop;
+
+               Project_2 := Project_2.Extends;
+            end loop Big_Loop_2;
+
+            List := Element.Next;
+         end loop;
+
+         Project.Interfaces_Defined := True;
+
+      elsif Project.Extends /= No_Project
+        and then Project.Extends.Interfaces_Defined
+      then
+         Project.Interfaces_Defined := True;
+
+         Iter := For_Each_Source (Data.Tree, Project);
+         loop
+            Source := Prj.Element (Iter);
+            exit when Source = No_Source;
+
+            if not Source.Declared_In_Interfaces then
+               Source.In_Interfaces := False;
+            end if;
+
+            Next (Iter);
+         end loop;
       end if;
    end Check_Interfaces;
 
@@ -2560,19 +2718,20 @@ package body Prj.Nmsc is
    --------------------------
 
    procedure Check_Package_Naming
-     (Project        : Project_Id;
-      Data           : in out Tree_Processing_Data;
-      Bodies         : out Array_Element_Id;
-      Specs          : out Array_Element_Id)
+     (Project : Project_Id;
+      Data    : in out Tree_Processing_Data;
+      Bodies  : out Array_Element_Id;
+      Specs   : out Array_Element_Id)
    is
       Naming_Id : constant Package_Id :=
-                 Util.Value_Of (Name_Naming, Project.Decl.Packages, Data.Tree);
+                    Util.Value_Of
+                      (Name_Naming, Project.Decl.Packages, Data.Tree);
       Naming    : Package_Element;
 
       Ada_Body_Suffix_Loc : Source_Ptr := No_Location;
 
-      procedure Check_Naming_Multi_Lang;
-      --  Does Check_Naming_Schemes processing for Multi_Language mode
+      procedure Check_Naming;
+      --  Check the validity of the Naming package (suffixes valid, ...)
 
       procedure Check_Common
         (Dot_Replacement : in out File_Name_Type;
@@ -2580,7 +2739,7 @@ package body Prj.Nmsc is
          Casing_Defined  : out Boolean;
          Separate_Suffix : in out File_Name_Type;
          Sep_Suffix_Loc  : out Source_Ptr);
-      --  Check attributes common to Ada_Only and Multi_Lang modes
+      --  Check attributes common
 
       procedure Process_Exceptions_File_Based
         (Lang_Id : Language_Ptr;
@@ -2588,8 +2747,7 @@ package body Prj.Nmsc is
       procedure Process_Exceptions_Unit_Based
         (Lang_Id : Language_Ptr;
          Kind    : Source_Kind);
-      --  In Multi_Lang mode, process the naming exceptions for the two types
-      --  of languages we can have.
+      --  Process the naming exceptions for the two types of languages
 
       procedure Initialize_Naming_Data;
       --  Initialize internal naming data for the various languages
@@ -2631,8 +2789,8 @@ package body Prj.Nmsc is
 
             if Length_Of_Name (Dot_Repl.Value) = 0 then
                Error_Msg
-                 (Project, "Dot_Replacement cannot be empty",
-                  Dot_Repl.Location, Data);
+                 (Data.Flags, "Dot_Replacement cannot be empty",
+                  Dot_Repl.Location, Project);
             end if;
 
             Dot_Replacement := Canonical_Case_File_Name (Dot_Repl.Value);
@@ -2662,10 +2820,10 @@ package body Prj.Nmsc is
                              Index (Source => Repl, Pattern => ".") /= 0)
                then
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      '"' & Repl &
                      """ is illegal for Dot_Replacement.",
-                     Dot_Repl_Loc, Data);
+                     Dot_Repl_Loc, Project);
                end if;
             end;
          end if;
@@ -2688,9 +2846,9 @@ package body Prj.Nmsc is
             begin
                if Casing_Image'Length = 0 then
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "Casing cannot be an empty string",
-                     Casing_String.Location, Data);
+                     Casing_String.Location, Project);
                end if;
 
                Casing := Value (Casing_Image);
@@ -2702,9 +2860,9 @@ package body Prj.Nmsc is
                   Name_Buffer (1 .. Name_Len) := Casing_Image;
                   Err_Vars.Error_Msg_Name_1 := Name_Find;
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "%% is not a correct Casing",
-                     Casing_String.Location, Data);
+                     Casing_String.Location, Project);
             end;
          end if;
 
@@ -2713,9 +2871,9 @@ package body Prj.Nmsc is
          if not Sep_Suffix.Default then
             if Length_Of_Name (Sep_Suffix.Value) = 0 then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "Separate_Suffix cannot be empty",
-                  Sep_Suffix.Location, Data);
+                  Sep_Suffix.Location, Project);
 
             else
                Separate_Suffix := Canonical_Case_File_Name (Sep_Suffix.Value);
@@ -2791,6 +2949,7 @@ package body Prj.Nmsc is
                     (Id               => Source,
                      Data             => Data,
                      Project          => Project,
+                     Source_Dir_Rank  => 0,
                      Lang_Id          => Lang_Id,
                      Kind             => Kind,
                      File_Name        => File_Name,
@@ -2803,15 +2962,15 @@ package body Prj.Nmsc is
 
                   if Source.Language /= Lang_Id then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "the same file cannot be a source of two languages",
-                        Element.Location, Data);
+                        Element.Location, Project);
 
                   elsif Source.Kind /= Kind then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "the same file cannot be a source and a template",
-                        Element.Location, Data);
+                        Element.Location, Project);
                   end if;
 
                   --  If the file is already recorded for the same
@@ -2833,21 +2992,22 @@ package body Prj.Nmsc is
         (Lang_Id : Language_Ptr;
          Kind    : Source_Kind)
       is
-         Lang              : constant Name_Id := Lang_Id.Name;
-         Exceptions        : Array_Element_Id;
-         Element           : Array_Element;
-         Unit              : Name_Id;
-         Index             : Int;
-         File_Name         : File_Name_Type;
-         Source            : Source_Id;
+         Lang       : constant Name_Id := Lang_Id.Name;
+         Exceptions : Array_Element_Id;
+         Element    : Array_Element;
+         Unit       : Name_Id;
+         Index      : Int;
+         File_Name  : File_Name_Type;
+         Source     : Source_Id;
 
       begin
          case Kind is
             when Impl | Sep =>
-               Exceptions := Value_Of
-                 (Name_Body,
-                  In_Arrays => Naming.Decl.Arrays,
-                  In_Tree   => Data.Tree);
+               Exceptions :=
+                 Value_Of
+                   (Name_Body,
+                    In_Arrays => Naming.Decl.Arrays,
+                    In_Tree   => Data.Tree);
 
                if Exceptions = No_Array_Element then
                   Exceptions :=
@@ -2865,10 +3025,11 @@ package body Prj.Nmsc is
                     In_Tree   => Data.Tree);
 
                if Exceptions = No_Array_Element then
-                  Exceptions := Value_Of
-                    (Name_Spec,
-                     In_Arrays => Naming.Decl.Arrays,
-                     In_Tree   => Data.Tree);
+                  Exceptions :=
+                    Value_Of
+                      (Name_Spec,
+                       In_Arrays => Naming.Decl.Arrays,
+                       In_Tree   => Data.Tree);
                end if;
          end case;
 
@@ -2890,23 +3051,25 @@ package body Prj.Nmsc is
                if Unit = No_Name then
                   Err_Vars.Error_Msg_Name_1 := Element.Index;
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "%% is not a valid unit name.",
-                     Element.Value.Location, Data);
+                     Element.Value.Location, Project);
                end if;
             end if;
 
             if Unit /= No_Name then
                Add_Source
-                 (Id           => Source,
-                  Data         => Data,
-                  Project      => Project,
-                  Lang_Id      => Lang_Id,
-                  Kind         => Kind,
-                  File_Name    => File_Name,
-                  Display_File => File_Name_Type (Element.Value.Value),
-                  Unit         => Unit,
-                  Index        => Index,
+                 (Id               => Source,
+                  Data             => Data,
+                  Project          => Project,
+                  Source_Dir_Rank  => 0,
+                  Lang_Id          => Lang_Id,
+                  Kind             => Kind,
+                  File_Name        => File_Name,
+                  Display_File     => File_Name_Type (Element.Value.Value),
+                  Unit             => Unit,
+                  Index            => Index,
+                  Location         => Element.Value.Location,
                   Naming_Exception => True);
             end if;
 
@@ -2914,13 +3077,14 @@ package body Prj.Nmsc is
          end loop;
       end Process_Exceptions_Unit_Based;
 
-      -----------------------------
-      -- Check_Naming_Multi_Lang --
-      -----------------------------
+      ------------------
+      -- Check_Naming --
+      ------------------
 
-      procedure Check_Naming_Multi_Lang is
+      procedure Check_Naming is
          Dot_Replacement : File_Name_Type :=
-           File_Name_Type (First_Name_Id + Character'Pos ('-'));
+                             File_Name_Type
+                               (First_Name_Id + Character'Pos ('-'));
          Separate_Suffix : File_Name_Type := No_File;
          Casing          : Casing_Type    := All_Lower_Case;
          Casing_Defined  : Boolean;
@@ -3002,18 +3166,20 @@ package body Prj.Nmsc is
 
             --  Body_Suffix
 
-            Suffix := Value_Of
-              (Name                    => Lang,
-               Attribute_Or_Array_Name => Name_Body_Suffix,
-               In_Package              => Naming_Id,
-               In_Tree                 => Data.Tree);
+            Suffix :=
+              Value_Of
+                (Name                    => Lang,
+                 Attribute_Or_Array_Name => Name_Body_Suffix,
+                 In_Package              => Naming_Id,
+                 In_Tree                 => Data.Tree);
 
             if Suffix = Nil_Variable_Value then
-               Suffix := Value_Of
-                 (Name                    => Lang,
-                  Attribute_Or_Array_Name => Name_Implementation_Suffix,
-                  In_Package              => Naming_Id,
-                  In_Tree                 => Data.Tree);
+               Suffix :=
+                 Value_Of
+                   (Name                    => Lang,
+                    Attribute_Or_Array_Name => Name_Implementation_Suffix,
+                    In_Package              => Naming_Id,
+                    In_Tree                 => Data.Tree);
             end if;
 
             if Suffix /= Nil_Variable_Value then
@@ -3057,28 +3223,28 @@ package body Prj.Nmsc is
 
             if Lang_Id.Config.Naming_Data.Spec_Suffix /= No_File
               and then Lang_Id.Config.Naming_Data.Spec_Suffix =
-                Lang_Id.Config.Naming_Data.Body_Suffix
+                       Lang_Id.Config.Naming_Data.Body_Suffix
             then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "Body_Suffix ("""
                   & Get_Name_String (Lang_Id.Config.Naming_Data.Body_Suffix)
                   & """) cannot be the same as Spec_Suffix.",
-                  Ada_Body_Suffix_Loc, Data);
+                  Ada_Body_Suffix_Loc, Project);
             end if;
 
             if Lang_Id.Config.Naming_Data.Body_Suffix /=
-              Lang_Id.Config.Naming_Data.Separate_Suffix
+               Lang_Id.Config.Naming_Data.Separate_Suffix
               and then Lang_Id.Config.Naming_Data.Spec_Suffix =
-                Lang_Id.Config.Naming_Data.Separate_Suffix
+                       Lang_Id.Config.Naming_Data.Separate_Suffix
             then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "Separate_Suffix ("""
                   & Get_Name_String
                     (Lang_Id.Config.Naming_Data.Separate_Suffix)
                   & """) cannot be the same as Spec_Suffix.",
-                  Sep_Suffix_Loc, Data);
+                  Sep_Suffix_Loc, Project);
             end if;
 
             Lang_Id := Lang_Id.Next;
@@ -3090,17 +3256,17 @@ package body Prj.Nmsc is
             Lang_Id := Project.Languages;
             while Lang_Id /= No_Language_Index loop
                case Lang_Id.Config.Kind is
-               when File_Based =>
-                  Process_Exceptions_File_Based (Lang_Id, Kind);
+                  when File_Based =>
+                     Process_Exceptions_File_Based (Lang_Id, Kind);
 
-               when Unit_Based =>
-                  Process_Exceptions_Unit_Based (Lang_Id, Kind);
+                  when Unit_Based =>
+                     Process_Exceptions_Unit_Based (Lang_Id, Kind);
                end case;
 
                Lang_Id := Lang_Id.Next;
             end loop;
          end loop;
-      end Check_Naming_Multi_Lang;
+      end Check_Naming;
 
       ----------------------------
       -- Initialize_Naming_Data --
@@ -3131,15 +3297,15 @@ package body Prj.Nmsc is
 
          while Specs /= No_Array_Element loop
             Lang_Name := Data.Tree.Array_Elements.Table (Specs).Index;
-            Lang := Get_Language_From_Name
-              (Project, Name => Get_Name_String (Lang_Name));
+            Lang :=
+              Get_Language_From_Name
+                (Project, Name => Get_Name_String (Lang_Name));
 
             --  An extending project inherits its parent projects' languages
             --  so if needed we should create entries for those languages
 
             if Lang = null  then
                Extended := Project.Extends;
-
                while Extended /= null loop
                   Lang := Get_Language_From_Name
                     (Extended, Name => Get_Name_String (Lang_Name));
@@ -3165,6 +3331,7 @@ package body Prj.Nmsc is
                      & Get_Name_String (Lang_Name)
                      & " since language is not defined for this project");
                end if;
+
             else
                Value := Data.Tree.Array_Elements.Table (Specs).Value;
 
@@ -3179,8 +3346,9 @@ package body Prj.Nmsc is
 
          while Impls /= No_Array_Element loop
             Lang_Name := Data.Tree.Array_Elements.Table (Impls).Index;
-            Lang := Get_Language_From_Name
-              (Project, Name => Get_Name_String (Lang_Name));
+            Lang :=
+              Get_Language_From_Name
+                (Project, Name => Get_Name_String (Lang_Name));
 
             if Lang = null then
                if Current_Verbosity = High then
@@ -3215,7 +3383,7 @@ package body Prj.Nmsc is
       --  No Naming package or parsing a configuration file? nothing to do
 
       if Naming_Id /= No_Package
-        and Project.Qualifier /= Configuration
+        and then Project.Qualifier /= Configuration
       then
          Naming := Data.Tree.Packages.Table (Naming_Id);
 
@@ -3225,7 +3393,7 @@ package body Prj.Nmsc is
          end if;
 
          Initialize_Naming_Data;
-         Check_Naming_Multi_Lang;
+         Check_Naming;
       end if;
    end Check_Package_Naming;
 
@@ -3279,8 +3447,8 @@ package body Prj.Nmsc is
       -------------------
 
       procedure Check_Library (Proj : Project_Id; Extends : Boolean) is
-         Src_Id    : Source_Id;
-         Iter      : Source_Iterator;
+         Src_Id : Source_Id;
+         Iter   : Source_Iterator;
 
       begin
          if Proj /= No_Project then
@@ -3306,11 +3474,11 @@ package body Prj.Nmsc is
                   if Extends then
                      if Project.Library_Kind /= Static then
                         Error_Msg
-                          (Project,
+                          (Data.Flags,
                            Continuation.all &
                            "shared library project %% cannot extend " &
                            "project %% that is not a library project",
-                           Project.Location, Data);
+                           Project.Location, Project);
                         Continuation := Continuation_String'Access;
                      end if;
 
@@ -3318,11 +3486,11 @@ package body Prj.Nmsc is
                         and then Project.Library_Kind /= Static
                   then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         Continuation.all &
                         "shared library project %% cannot import project %% " &
                         "that is not a shared library project",
-                        Project.Location, Data);
+                        Project.Location, Project);
                      Continuation := Continuation_String'Access;
                   end if;
                end if;
@@ -3335,20 +3503,20 @@ package body Prj.Nmsc is
 
                if Extends then
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      Continuation.all &
                      "shared library project %% cannot extend static " &
                      "library project %%",
-                     Project.Location, Data);
+                     Project.Location, Project);
                   Continuation := Continuation_String'Access;
 
                elsif not Unchecked_Shared_Lib_Imports then
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      Continuation.all &
                      "shared library project %% cannot import static " &
                      "library project %%",
-                     Project.Location, Data);
+                     Project.Location, Project);
                   Continuation := Continuation_String'Access;
                end if;
 
@@ -3374,9 +3542,9 @@ package body Prj.Nmsc is
          if Project.Extends.Library then
             if Project.Qualifier = Standard then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "a standard project cannot extend a library project",
-                  Project.Location, Data);
+                  Project.Location, Project);
 
             else
                if Lib_Name.Default then
@@ -3386,10 +3554,10 @@ package body Prj.Nmsc is
                if Lib_Dir.Default then
                   if not Project.Virtual then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "a project extending a library project must " &
                         "specify an attribute Library_Dir",
-                        Project.Location, Data);
+                        Project.Location, Project);
 
                   else
                      --  For a virtual project extending a library project,
@@ -3461,19 +3629,19 @@ package body Prj.Nmsc is
                Err_Vars.Error_Msg_File_1 :=
                  File_Name_Type (Project.Library_Dir.Display_Name);
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "library directory { does not exist",
-                  Lib_Dir.Location, Data);
+                  Lib_Dir.Location, Project);
 
                --  The library directory cannot be the same as the Object
                --  directory.
 
             elsif Project.Library_Dir.Name = Project.Object_Directory.Name then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "library directory cannot be the same " &
                   "as object directory",
-                  Lib_Dir.Location, Data);
+                  Lib_Dir.Location, Project);
                Project.Library_Dir := No_Path_Information;
 
             else
@@ -3498,10 +3666,10 @@ package body Prj.Nmsc is
                         Err_Vars.Error_Msg_File_1 :=
                           File_Name_Type (Dir_Elem.Value);
                         Error_Msg
-                          (Project,
+                          (Data.Flags,
                            "library directory cannot be the same " &
                            "as source directory {",
-                           Lib_Dir.Location, Data);
+                           Lib_Dir.Location, Project);
                         OK := False;
                         exit;
                      end if;
@@ -3532,10 +3700,10 @@ package body Prj.Nmsc is
                                  Err_Vars.Error_Msg_Name_1 := Pid.Project.Name;
 
                                  Error_Msg
-                                   (Project,
+                                   (Data.Flags,
                                     "library directory cannot be the same " &
                                     "as source directory { of project %%",
-                                    Lib_Dir.Location, Data);
+                                    Lib_Dir.Location, Project);
                                  OK := False;
                                  exit Project_Loop;
                               end if;
@@ -3572,25 +3740,25 @@ package body Prj.Nmsc is
             when Standard =>
                if Project.Library then
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "a standard project cannot be a library project",
-                     Lib_Name.Location, Data);
+                     Lib_Name.Location, Project);
                end if;
 
             when Library =>
                if not Project.Library then
                   if Project.Library_Dir = No_Path_Information then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "\attribute Library_Dir not declared",
-                        Project.Location, Data);
+                        Project.Location, Project);
                   end if;
 
                   if Project.Library_Name = No_Name then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "\attribute Library_Name not declared",
-                        Project.Location, Data);
+                        Project.Location, Project);
                   end if;
                end if;
 
@@ -3601,18 +3769,13 @@ package body Prj.Nmsc is
       end if;
 
       if Project.Library then
-         if Get_Mode = Multi_Language then
-            Support_For_Libraries := Project.Config.Lib_Support;
-
-         else
-            Support_For_Libraries := MLib.Tgt.Support_For_Libraries;
-         end if;
+         Support_For_Libraries := Project.Config.Lib_Support;
 
          if Support_For_Libraries = Prj.None then
             Error_Msg
-              (Project,
+              (Data.Flags,
                "?libraries are not supported on this platform",
-               Lib_Name.Location, Data);
+               Lib_Name.Location, Project);
             Project.Library := False;
 
          else
@@ -3645,9 +3808,9 @@ package body Prj.Nmsc is
                   Err_Vars.Error_Msg_File_1 :=
                     File_Name_Type (Project.Library_ALI_Dir.Display_Name);
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "library 'A'L'I directory { does not exist",
-                     Lib_ALI_Dir.Location, Data);
+                     Lib_ALI_Dir.Location, Project);
                end if;
 
                if Project.Library_ALI_Dir /= Project.Library_Dir then
@@ -3657,10 +3820,10 @@ package body Prj.Nmsc is
 
                   if Project.Library_ALI_Dir = Project.Object_Directory then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "library 'A'L'I directory cannot be the same " &
                         "as object directory",
-                        Lib_ALI_Dir.Location, Data);
+                        Lib_ALI_Dir.Location, Project);
                      Project.Library_ALI_Dir := No_Path_Information;
 
                   else
@@ -3686,10 +3849,10 @@ package body Prj.Nmsc is
                               Err_Vars.Error_Msg_File_1 :=
                                 File_Name_Type (Dir_Elem.Value);
                               Error_Msg
-                                (Project,
+                                (Data.Flags,
                                  "library 'A'L'I directory cannot be " &
                                  "the same as source directory {",
-                                 Lib_ALI_Dir.Location, Data);
+                                 Lib_ALI_Dir.Location, Project);
                               OK := False;
                               exit;
                            end if;
@@ -3723,11 +3886,11 @@ package body Prj.Nmsc is
                                          Pid.Project.Name;
 
                                        Error_Msg
-                                         (Project,
+                                         (Data.Flags,
                                           "library 'A'L'I directory cannot " &
                                           "be the same as source directory " &
                                           "{ of project %%",
-                                          Lib_ALI_Dir.Location, Data);
+                                          Lib_ALI_Dir.Location, Project);
                                        OK := False;
                                        exit ALI_Project_Loop;
                                     end if;
@@ -3793,9 +3956,9 @@ package body Prj.Nmsc is
 
                   else
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "illegal value for Library_Kind",
-                        The_Lib_Kind.Location, Data);
+                        The_Lib_Kind.Location, Project);
                      OK := False;
                   end if;
 
@@ -3806,10 +3969,10 @@ package body Prj.Nmsc is
                   if Project.Library_Kind /= Static then
                      if Support_For_Libraries = Prj.Static_Only then
                         Error_Msg
-                          (Project,
+                          (Data.Flags,
                            "only static libraries are supported " &
                            "on this platform",
-                           The_Lib_Kind.Location, Data);
+                           The_Lib_Kind.Location, Project);
                         Project.Library := False;
 
                      else
@@ -3818,10 +3981,10 @@ package body Prj.Nmsc is
 
                         if Lib_GCC.Value /= Empty_String then
                            Error_Msg
-                             (Project,
+                             (Data.Flags,
                               "?Library_'G'C'C is an obsolescent attribute, " &
                               "use Linker''Driver instead",
-                              Lib_GCC.Location, Data);
+                              Lib_GCC.Location, Project);
                            Project.Config.Shared_Lib_Driver :=
                              File_Name_Type (Lib_GCC.Value);
 
@@ -3859,17 +4022,15 @@ package body Prj.Nmsc is
                   Write_Line ("This is a library project file");
                end if;
 
-               if Get_Mode = Multi_Language then
-                  Check_Library (Project.Extends, Extends => True);
+               Check_Library (Project.Extends, Extends => True);
 
-                  Imported_Project_List := Project.Imported_Projects;
-                  while Imported_Project_List /= null loop
-                     Check_Library
-                       (Imported_Project_List.Project,
-                        Extends => False);
-                     Imported_Project_List := Imported_Project_List.Next;
-                  end loop;
-               end if;
+               Imported_Project_List := Project.Imported_Projects;
+               while Imported_Project_List /= null loop
+                  Check_Library
+                    (Imported_Project_List.Project,
+                     Extends => False);
+                  Imported_Project_List := Imported_Project_List.Next;
+               end loop;
             end if;
 
          end if;
@@ -3908,10 +4069,10 @@ package body Prj.Nmsc is
 
                if Switches /= No_Array_Element then
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "?Linker switches not taken into account in library " &
                      "projects",
-                     No_Location, Data);
+                     No_Location, Project);
                end if;
             end if;
          end;
@@ -3958,29 +4119,12 @@ package body Prj.Nmsc is
          Lang              := new Language_Data'(No_Language_Data);
          Lang.Next         := Project.Languages;
          Project.Languages := Lang;
-         Lang.Name := Name;
+         Lang.Name         := Name;
          Lang.Display_Name := Display_Name;
 
          if Name = Name_Ada then
-            Lang.Config.Kind := Unit_Based;
+            Lang.Config.Kind            := Unit_Based;
             Lang.Config.Dependency_Kind := ALI_File;
-
-            if Get_Mode = Ada_Only then
-
-               --  Create a default config for Ada (since there is no
-               --  configuration file to create it for us).
-
-               --  ??? We should do as GPS does and create a dummy config file
-
-               Lang.Config.Naming_Data :=
-                 (Dot_Replacement => File_Name_Type
-                    (First_Name_Id + Character'Pos ('-')),
-                  Casing          => All_Lower_Case,
-                  Separate_Suffix => Default_Ada_Body_Suffix,
-                  Spec_Suffix     => Default_Ada_Spec_Suffix,
-                  Body_Suffix     => Default_Ada_Body_Suffix);
-            end if;
-
          else
             Lang.Config.Kind := File_Based;
          end if;
@@ -3996,40 +4140,25 @@ package body Prj.Nmsc is
         Prj.Util.Value_Of
           (Name_Default_Language, Project.Decl.Attributes, Data.Tree);
 
-      --  Shouldn't these be set to False by default, and only set to True when
-      --  we actually find some source file???
-
       if Project.Source_Dirs /= Nil_String then
 
          --  Check if languages are specified in this project
 
          if Languages.Default then
 
-            --  In Ada_Only mode, the default language is Ada
+            --  Fail if there is no default language defined
 
-            if Get_Mode = Ada_Only then
-               Def_Lang_Id := Name_Ada;
+            if Def_Lang.Default then
+               Error_Msg
+                 (Data.Flags,
+                  "no languages defined for this project",
+                  Project.Location, Project);
+               Def_Lang_Id := No_Name;
 
             else
-               --  Fail if there is no default language defined
-
-               if Def_Lang.Default then
-                  if not Default_Language_Is_Ada then
-                     Error_Msg
-                       (Project,
-                        "no languages defined for this project",
-                        Project.Location, Data);
-                     Def_Lang_Id := No_Name;
-
-                  else
-                     Def_Lang_Id := Name_Ada;
-                  end if;
-
-               else
-                  Get_Name_String (Def_Lang.Value);
-                  To_Lower (Name_Buffer (1 .. Name_Len));
-                  Def_Lang_Id := Name_Find;
-               end if;
+               Get_Name_String (Def_Lang.Value);
+               To_Lower (Name_Buffer (1 .. Name_Len));
+               Def_Lang_Id := Name_Find;
             end if;
 
             if Def_Lang_Id /= No_Name then
@@ -4053,9 +4182,9 @@ package body Prj.Nmsc is
 
                   if Project.Qualifier = Standard then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "a standard project must have at least one language",
-                        Languages.Location, Data);
+                        Languages.Location, Project);
                   end if;
 
                else
@@ -4079,44 +4208,13 @@ package body Prj.Nmsc is
       end if;
    end Check_Programming_Languages;
 
-   -------------------
-   -- Check_Project --
-   -------------------
+   -------------------------------
+   -- Check_Stand_Alone_Library --
+   -------------------------------
 
-   function Check_Project
-     (P            : Project_Id;
-      Root_Project : Project_Id;
-      Extending    : Boolean) return Boolean
-   is
-      Prj : Project_Id;
-
-   begin
-      if P = Root_Project then
-         return True;
-
-      elsif Extending then
-         Prj := Root_Project;
-         while Prj.Extends /= No_Project loop
-            if P = Prj.Extends then
-               return True;
-            end if;
-
-            Prj := Prj.Extends;
-         end loop;
-      end if;
-
-      return False;
-   end Check_Project;
-
-   -------------------------------
-   -- Check_Stand_Alone_Library --
-   -------------------------------
-
-   procedure Check_Stand_Alone_Library
-     (Project     : Project_Id;
-      Current_Dir : String;
-      Extending   : Boolean;
-      Data        : in out Tree_Processing_Data)
+   procedure Check_Stand_Alone_Library
+     (Project : Project_Id;
+      Data    : in out Tree_Processing_Data)
    is
       Lib_Interfaces      : constant Prj.Variable_Value :=
                               Prj.Util.Value_Of
@@ -4161,12 +4259,7 @@ package body Prj.Nmsc is
       Iter                : Source_Iterator;
 
    begin
-      if Get_Mode = Multi_Language then
-         Auto_Init_Supported := Project.Config.Auto_Init_Supported;
-      else
-         Auto_Init_Supported :=
-           MLib.Tgt.Standalone_Library_Auto_Init_Is_Supported;
-      end if;
+      Auto_Init_Supported := Project.Config.Auto_Init_Supported;
 
       pragma Assert (Lib_Interfaces.Kind = List);
 
@@ -4174,52 +4267,10 @@ package body Prj.Nmsc is
       --  Library_Interface is defined.
 
       if not Lib_Interfaces.Default then
-         SAL_Library : declare
+         declare
             Interfaces     : String_List_Id := Lib_Interfaces.Values;
             Interface_ALIs : String_List_Id := Nil_String;
             Unit           : Name_Id;
-            UData          : Unit_Index;
-
-            procedure Add_ALI_For (Source : File_Name_Type);
-            --  Add an ALI file name to the list of Interface ALIs
-
-            -----------------
-            -- Add_ALI_For --
-            -----------------
-
-            procedure Add_ALI_For (Source : File_Name_Type) is
-            begin
-               Get_Name_String (Source);
-
-               declare
-                  ALI         : constant String :=
-                                  ALI_File_Name (Name_Buffer (1 .. Name_Len));
-                  ALI_Name_Id : Name_Id;
-
-               begin
-                  Name_Len := ALI'Length;
-                  Name_Buffer (1 .. Name_Len) := ALI;
-                  ALI_Name_Id := Name_Find;
-
-                  String_Element_Table.Increment_Last
-                    (Data.Tree.String_Elements);
-                  Data.Tree.String_Elements.Table
-                    (String_Element_Table.Last
-                      (Data.Tree.String_Elements)) :=
-                    (Value         => ALI_Name_Id,
-                     Index         => 0,
-                     Display_Value => ALI_Name_Id,
-                     Location      =>
-                       Data.Tree.String_Elements.Table
-                         (Interfaces).Location,
-                     Flag          => False,
-                     Next          => Interface_ALIs);
-                  Interface_ALIs := String_Element_Table.Last
-                                      (Data.Tree.String_Elements);
-               end;
-            end Add_ALI_For;
-
-         --  Start of processing for SAL_Library
 
          begin
             Project.Standalone_Library := True;
@@ -4228,9 +4279,9 @@ package body Prj.Nmsc is
 
             if Interfaces = Nil_String then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "Library_Interface cannot be an empty list",
-                  Lib_Interfaces.Location, Data);
+                  Lib_Interfaces.Location, Project);
             end if;
 
             --  Process each unit name specified in the attribute
@@ -4243,182 +4294,89 @@ package body Prj.Nmsc is
 
                if Name_Len = 0 then
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "an interface cannot be an empty string",
                      Data.Tree.String_Elements.Table (Interfaces).Location,
-                     Data);
+                     Project);
 
                else
                   Unit := Name_Find;
                   Error_Msg_Name_1 := Unit;
 
-                  if Get_Mode = Ada_Only then
-                     UData := Units_Htable.Get (Data.Tree.Units_HT, Unit);
-
-                     if UData = No_Unit_Index then
-                        Error_Msg
-                          (Project,
-                           "unknown unit %%",
-                           Data.Tree.String_Elements.Table
-                             (Interfaces).Location, Data);
-
-                     else
-                        --  Check that the unit is part of the project
-
-                        if UData.File_Names (Impl) /= null
-                          and then not UData.File_Names (Impl).Locally_Removed
-                        then
-                           if Check_Project
-                             (UData.File_Names (Impl).Project,
-                              Project, 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 UData.File_Names (Spec) = null then
-                                 declare
-                                    Src_Ind : Source_File_Index;
-
-                                 begin
-                                    Src_Ind :=
-                                      Sinput.P.Load_Project_File
-                                        (Get_Name_String (UData.File_Names
-                                                           (Impl).Path.Name));
-
-                                    if Sinput.P.Source_File_Is_Subunit
-                                        (Src_Ind)
-                                    then
-                                       Error_Msg
-                                         (Project,
-                                          "%% is a subunit; " &
-                                          "it cannot be an interface",
-                                          Data.Tree.
-                                            String_Elements.Table
-                                              (Interfaces).Location,
-                                          Data);
-                                    end if;
-                                 end;
-                              end if;
-
-                              --  The unit is not a subunit, so we add the
-                              --  ALI file for its body to the Interface ALIs.
-
-                              Add_ALI_For
-                                (UData.File_Names (Impl).File);
-
-                           else
-                              Error_Msg
-                                (Project,
-                                 "%% is not an unit of this project",
-                                 Data.Tree.String_Elements.Table
-                                   (Interfaces).Location, Data);
-                           end if;
-
-                        elsif UData.File_Names (Spec) /= null
-                          and then not UData.File_Names (Spec).Locally_Removed
-                          and then Check_Project
-                                     (UData.File_Names (Spec).Project,
-                                      Project, Extending)
-
-                        then
-                           --  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
-                             (UData.File_Names (Spec).File);
-
-                        else
-                           Error_Msg
-                             (Project,
-                              "%% is not an unit of this project",
-                              Data.Tree.String_Elements.Table
-                                (Interfaces).Location, Data);
-                        end if;
-                     end if;
-
-                  else
-                     --  Multi_Language mode
-
-                     Next_Proj := Project.Extends;
-                     Iter := For_Each_Source (Data.Tree, Project);
+                  Next_Proj := Project.Extends;
+                  Iter := For_Each_Source (Data.Tree, Project);
+                  loop
+                     while Prj.Element (Iter) /= No_Source
+                       and then
+                         (Prj.Element (Iter).Unit = null
+                           or else Prj.Element (Iter).Unit.Name /= Unit)
                      loop
-                        while Prj.Element (Iter) /= No_Source
-                          and then
-                            (Prj.Element (Iter).Unit = null
-                              or else Prj.Element (Iter).Unit.Name /= Unit)
-                        loop
-                           Next (Iter);
-                        end loop;
+                        Next (Iter);
+                     end loop;
 
-                        Source := Prj.Element (Iter);
-                        exit when Source /= No_Source
-                          or else Next_Proj = No_Project;
+                     Source := Prj.Element (Iter);
+                     exit when Source /= No_Source
+                       or else Next_Proj = No_Project;
 
-                        Iter := For_Each_Source (Data.Tree, Next_Proj);
-                        Next_Proj := Next_Proj.Extends;
-                     end loop;
+                     Iter := For_Each_Source (Data.Tree, Next_Proj);
+                     Next_Proj := Next_Proj.Extends;
+                  end loop;
 
-                     if Source /= No_Source then
-                        if Source.Kind = Sep then
-                           Source := No_Source;
+                  if Source /= No_Source then
+                     if Source.Kind = Sep then
+                        Source := No_Source;
 
-                        elsif Source.Kind = Spec
-                          and then Other_Part (Source) /= No_Source
-                        then
-                           Source := Other_Part (Source);
-                        end if;
+                     elsif Source.Kind = Spec
+                       and then Other_Part (Source) /= No_Source
+                     then
+                        Source := Other_Part (Source);
                      end if;
+                  end if;
 
-                     if Source /= No_Source then
-                        if Source.Project /= Project
-                          and then not Is_Extending (Project, Source.Project)
-                        then
-                           Source := No_Source;
-                        end if;
+                  if Source /= No_Source then
+                     if Source.Project /= Project
+                       and then not Is_Extending (Project, Source.Project)
+                     then
+                        Source := No_Source;
                      end if;
+                  end if;
 
-                     if Source = No_Source then
-                           Error_Msg
-                             (Project,
-                              "%% is not an unit of this project",
-                              Data.Tree.String_Elements.Table
-                                (Interfaces).Location, Data);
-
-                     else
-                        if Source.Kind = Spec
-                          and then Other_Part (Source) /= No_Source
-                        then
-                           Source := Other_Part (Source);
-                        end if;
-
-                        String_Element_Table.Increment_Last
-                          (Data.Tree.String_Elements);
-
+                  if Source = No_Source then
+                     Error_Msg
+                       (Data.Flags,
+                        "%% is not a unit of this project",
                         Data.Tree.String_Elements.Table
-                          (String_Element_Table.Last
-                             (Data.Tree.String_Elements)) :=
-                          (Value         => Name_Id (Source.Dep_Name),
-                           Index         => 0,
-                           Display_Value => Name_Id (Source.Dep_Name),
-                           Location      =>
-                             Data.Tree.String_Elements.Table
-                               (Interfaces).Location,
-                           Flag          => False,
-                           Next          => Interface_ALIs);
-
-                        Interface_ALIs :=
-                          String_Element_Table.Last
-                            (Data.Tree.String_Elements);
+                          (Interfaces).Location, Project);
+
+                  else
+                     if Source.Kind = Spec
+                       and then Other_Part (Source) /= No_Source
+                     then
+                        Source := Other_Part (Source);
                      end if;
 
+                     String_Element_Table.Increment_Last
+                       (Data.Tree.String_Elements);
+
+                     Data.Tree.String_Elements.Table
+                       (String_Element_Table.Last
+                          (Data.Tree.String_Elements)) :=
+                       (Value         => Name_Id (Source.Dep_Name),
+                        Index         => 0,
+                        Display_Value => Name_Id (Source.Dep_Name),
+                        Location      =>
+                          Data.Tree.String_Elements.Table
+                            (Interfaces).Location,
+                        Flag          => False,
+                        Next          => Interface_ALIs);
+
+                     Interface_ALIs :=
+                       String_Element_Table.Last
+                         (Data.Tree.String_Elements);
                   end if;
-
                end if;
 
-               Interfaces :=
-                 Data.Tree.String_Elements.Table (Interfaces).Next;
+               Interfaces := Data.Tree.String_Elements.Table (Interfaces).Next;
             end loop;
 
             --  Put the list of Interface ALIs in the project data
@@ -4451,20 +4409,20 @@ package body Prj.Nmsc is
                      --  supported.
 
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "library auto init not supported " &
                         "on this platform",
-                        Lib_Auto_Init.Location, Data);
+                        Lib_Auto_Init.Location, Project);
                   end if;
 
                else
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "invalid value for attribute Library_Auto_Init",
-                     Lib_Auto_Init.Location, Data);
+                     Lib_Auto_Init.Location, Project);
                end if;
             end if;
-         end SAL_Library;
+         end;
 
          --  If attribute Library_Src_Dir is defined and not the empty string,
          --  check if the directory exist and is not the object directory or
@@ -4484,7 +4442,7 @@ package body Prj.Nmsc is
                   Dir_Id,
                   Path             => Project.Library_Src_Dir,
                   Dir_Exists       => Dir_Exists,
-                  Data        => Data,
+                  Data             => Data,
                   Must_Exist       => False,
                   Create           => "library source copy",
                   Location         => Lib_Src_Dir.Location,
@@ -4500,18 +4458,18 @@ package body Prj.Nmsc is
                   Err_Vars.Error_Msg_File_1 :=
                     File_Name_Type (Project.Library_Src_Dir.Display_Name);
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "Directory { does not exist",
-                     Lib_Src_Dir.Location, Data);
+                     Lib_Src_Dir.Location, Project);
 
                   --  Report error if it is the same as the object directory
 
                elsif Project.Library_Src_Dir = Project.Object_Directory then
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "directory to copy interfaces cannot be " &
                      "the object directory",
-                     Lib_Src_Dir.Location, Data);
+                     Lib_Src_Dir.Location, Project);
                   Project.Library_Src_Dir := No_Path_Information;
 
                else
@@ -4531,13 +4489,13 @@ package body Prj.Nmsc is
                         --  Report error if it is one of the source directories
 
                         if Project.Library_Src_Dir.Name =
-                          Path_Name_Type (Src_Dir.Value)
+                             Path_Name_Type (Src_Dir.Value)
                         then
                            Error_Msg
-                             (Project,
+                             (Data.Flags,
                               "directory to copy interfaces cannot " &
                               "be one of the source directories",
-                              Lib_Src_Dir.Location, Data);
+                              Lib_Src_Dir.Location, Project);
                            Project.Library_Src_Dir := No_Path_Information;
                            exit;
                         end if;
@@ -4560,7 +4518,7 @@ package body Prj.Nmsc is
                                 Data.Tree.String_Elements.Table (Src_Dirs);
 
                               --  Report error if it is one of the source
-                              --  directories
+                              --  directories.
 
                               if Project.Library_Src_Dir.Name =
                                 Path_Name_Type (Src_Dir.Value)
@@ -4569,11 +4527,11 @@ package body Prj.Nmsc is
                                    File_Name_Type (Src_Dir.Value);
                                  Error_Msg_Name_1 := Pid.Project.Name;
                                  Error_Msg
-                                   (Project,
+                                   (Data.Flags,
                                     "directory to copy interfaces cannot " &
                                     "be the same as source directory { of " &
                                     "project %%",
-                                    Lib_Src_Dir.Location, Data);
+                                    Lib_Src_Dir.Location, Project);
                                  Project.Library_Src_Dir :=
                                    No_Path_Information;
                                  exit Project_Loop;
@@ -4608,8 +4566,8 @@ package body Prj.Nmsc is
          if not Lib_Symbol_Policy.Default then
             declare
                Value : constant String :=
-                 To_Lower
-                   (Get_Name_String (Lib_Symbol_Policy.Value));
+                         To_Lower
+                           (Get_Name_String (Lib_Symbol_Policy.Value));
 
             begin
                --  Symbol policy must hove one of a limited number of values
@@ -4631,9 +4589,9 @@ package body Prj.Nmsc is
 
                else
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "illegal value for Library_Symbol_Policy",
-                     Lib_Symbol_Policy.Location, Data);
+                     Lib_Symbol_Policy.Location, Project);
                end if;
             end;
          end if;
@@ -4644,10 +4602,10 @@ package body Prj.Nmsc is
          if Lib_Symbol_File.Default then
             if Project.Symbol_Data.Symbol_Policy = Restricted then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "Library_Symbol_File needs to be defined when " &
                   "symbol policy is Restricted",
-                  Lib_Symbol_Policy.Location, Data);
+                  Lib_Symbol_Policy.Location, Project);
             end if;
 
          else
@@ -4660,9 +4618,9 @@ package body Prj.Nmsc is
 
             if Name_Len = 0 then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "symbol file name cannot be an empty string",
-                  Lib_Symbol_File.Location, Data);
+                  Lib_Symbol_File.Location, Project);
 
             else
                OK := not Is_Absolute_Path (Name_Buffer (1 .. Name_Len));
@@ -4681,10 +4639,10 @@ package body Prj.Nmsc is
                if not OK then
                   Error_Msg_File_1 := File_Name_Type (Lib_Symbol_File.Value);
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "symbol file name { is illegal. " &
                      "Name cannot include directory info.",
-                     Lib_Symbol_File.Location, Data);
+                     Lib_Symbol_File.Location, Project);
                end if;
             end if;
          end if;
@@ -4697,9 +4655,9 @@ package body Prj.Nmsc is
               or else Project.Symbol_Data.Symbol_Policy = Controlled
             then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "a reference symbol file needs to be defined",
-                  Lib_Symbol_Policy.Location, Data);
+                  Lib_Symbol_Policy.Location, Project);
             end if;
 
          else
@@ -4712,9 +4670,9 @@ package body Prj.Nmsc is
 
             if Name_Len = 0 then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "reference symbol file name cannot be an empty string",
-                  Lib_Symbol_File.Location, Data);
+                  Lib_Symbol_File.Location, Project);
 
             else
                if not Is_Absolute_Path (Name_Buffer (1 .. Name_Len)) then
@@ -4727,7 +4685,7 @@ package body Prj.Nmsc is
                end if;
 
                if not Is_Regular_File
-                 (Get_Name_String (Project.Symbol_Data.Reference))
+                        (Get_Name_String (Project.Symbol_Data.Reference))
                then
                   Error_Msg_File_1 :=
                     File_Name_Type (Lib_Ref_Symbol_File.Value);
@@ -4741,9 +4699,9 @@ package body Prj.Nmsc is
                     and then Project.Symbol_Data.Symbol_Policy /= Direct;
 
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "<library reference symbol file { does not exist",
-                     Lib_Ref_Symbol_File.Location, Data);
+                     Lib_Ref_Symbol_File.Location, Project);
 
                   --  In addition in the non-controlled case, if symbol policy
                   --  is Compliant, it is changed to Autonomous, because there
@@ -4765,28 +4723,32 @@ package body Prj.Nmsc is
 
                   if Name_Len > 0 then
                      declare
+                        --  We do not need to pass a Directory to
+                        --  Normalize_Pathname, since the path_information
+                        --  already contains absolute information.
+
                         Symb_Path : constant String :=
                                       Normalize_Pathname
                                         (Get_Name_String
                                            (Project.Object_Directory.Name) &
                                          Name_Buffer (1 .. Name_Len),
-                                         Directory     => Current_Dir,
+                                         Directory     => "/",
                                          Resolve_Links =>
                                            Opt.Follow_Links_For_Files);
                         Ref_Path  : constant String :=
                                       Normalize_Pathname
                                         (Get_Name_String
                                            (Project.Symbol_Data.Reference),
-                                         Directory     => Current_Dir,
+                                         Directory     => "/",
                                          Resolve_Links =>
                                            Opt.Follow_Links_For_Files);
                      begin
                         if Symb_Path = Ref_Path then
                            Error_Msg
-                             (Project,
+                             (Data.Flags,
                               "library reference symbol file and library" &
                               " symbol file cannot be the same file",
-                              Lib_Ref_Symbol_File.Location, Data);
+                              Lib_Ref_Symbol_File.Location, Project);
                         end if;
                      end;
                   end if;
@@ -4804,7 +4766,8 @@ package body Prj.Nmsc is
    begin
       if Dir'Length > 1
         and then (Dir (Dir'Last - 1) = Directory_Separator
-                   or else Dir (Dir'Last - 1) = '/')
+                    or else
+                  Dir (Dir'Last - 1) = '/')
       then
          return Dir'Last - 1;
       else
@@ -4812,170 +4775,12 @@ package body Prj.Nmsc is
       end if;
    end Compute_Directory_Last;
 
-   ---------------
-   -- Error_Msg --
-   ---------------
-
-   procedure Error_Msg
-     (Project       : Project_Id;
-      Msg           : String;
-      Flag_Location : Source_Ptr;
-      Data          : Tree_Processing_Data)
-   is
-      Real_Location : Source_Ptr := Flag_Location;
-      Error_Buffer  : String (1 .. 5_000);
-      Error_Last    : Natural := 0;
-      Name_Number   : Natural := 0;
-      File_Number   : Natural := 0;
-      First         : Positive := Msg'First;
-      Index         : Positive;
-
-      procedure Add (C : Character);
-      --  Add a character to the buffer
-
-      procedure Add (S : String);
-      --  Add a string to the buffer
-
-      procedure Add_Name;
-      --  Add a name to the buffer
-
-      procedure Add_File;
-      --  Add a file name to the buffer
-
-      ---------
-      -- Add --
-      ---------
-
-      procedure Add (C : Character) is
-      begin
-         Error_Last := Error_Last + 1;
-         Error_Buffer (Error_Last) := C;
-      end Add;
-
-      procedure Add (S : String) is
-      begin
-         Error_Buffer (Error_Last + 1 .. Error_Last + S'Length) := S;
-         Error_Last := Error_Last + S'Length;
-      end Add;
-
-      --------------
-      -- Add_File --
-      --------------
-
-      procedure Add_File is
-         File : File_Name_Type;
-
-      begin
-         Add ('"');
-         File_Number := File_Number + 1;
-
-         case File_Number is
-            when 1 =>
-               File := Err_Vars.Error_Msg_File_1;
-            when 2 =>
-               File := Err_Vars.Error_Msg_File_2;
-            when 3 =>
-               File := Err_Vars.Error_Msg_File_3;
-            when others =>
-               null;
-         end case;
-
-         Get_Name_String (File);
-         Add (Name_Buffer (1 .. Name_Len));
-         Add ('"');
-      end Add_File;
-
-      --------------
-      -- Add_Name --
-      --------------
-
-      procedure Add_Name is
-         Name : Name_Id;
-
-      begin
-         Add ('"');
-         Name_Number := Name_Number + 1;
-
-         case Name_Number is
-            when 1 =>
-               Name := Err_Vars.Error_Msg_Name_1;
-            when 2 =>
-               Name := Err_Vars.Error_Msg_Name_2;
-            when 3 =>
-               Name := Err_Vars.Error_Msg_Name_3;
-            when others =>
-               null;
-         end case;
-
-         Get_Name_String (Name);
-         Add (Name_Buffer (1 .. Name_Len));
-         Add ('"');
-      end Add_Name;
-
-   --  Start of processing for Error_Msg
-
-   begin
-      --  If location of error is unknown, use the location of the project
-
-      if Real_Location = No_Location then
-         Real_Location := Project.Location;
-      end if;
-
-      if Data.Report_Error = null then
-         Prj.Err.Error_Msg (Msg, Real_Location);
-         return;
-      end if;
-
-      --  Ignore continuation character
-
-      if Msg (First) = '\' then
-         First := First + 1;
-      end if;
-
-      --  Warning character is always the first one in this package
-      --  this is an undocumented kludge???
-
-      if Msg (First) = '?' then
-         First := First + 1;
-         Add ("Warning: ");
-
-      elsif Msg (First) = '<' then
-         First := First + 1;
-
-         if Err_Vars.Error_Msg_Warn then
-            Add ("Warning: ");
-         end if;
-      end if;
-
-      Index := First;
-      while Index <= Msg'Last loop
-         if Msg (Index) = '{' then
-            Add_File;
-
-         elsif Msg (Index) = '%' then
-            if Index < Msg'Last and then Msg (Index + 1) = '%' then
-               Index := Index + 1;
-            end if;
-
-            Add_Name;
-         else
-            Add (Msg (Index));
-         end if;
-         Index := Index + 1;
-
-      end loop;
-
-      Data.Report_Error
-        (Error_Buffer (1 .. Error_Last), Project, Data.Tree);
-   end Error_Msg;
-
    ---------------------
    -- Get_Directories --
    ---------------------
 
    procedure Get_Directories
      (Project     : Project_Id;
-      Current_Dir : String;
       Data        : in out Tree_Processing_Data)
    is
       package Recursive_Dirs is new GNAT.Dynamic_HTables.Simple_HTable
@@ -5014,7 +4819,8 @@ package body Prj.Nmsc is
                         (Name_Source_Files,
                          Project.Decl.Attributes, Data.Tree);
 
-      Last_Source_Dir : String_List_Id  := Nil_String;
+      Last_Source_Dir   : String_List_Id    := Nil_String;
+      Last_Src_Dir_Rank : Number_List_Index := No_Number_List;
 
       Languages : constant Variable_Value :=
                       Prj.Util.Value_Of
@@ -5023,6 +4829,7 @@ package body Prj.Nmsc is
       procedure Find_Source_Dirs
         (From     : File_Name_Type;
          Location : Source_Ptr;
+         Rank     : Natural;
          Removed  : Boolean := False);
       --  Find one or several source directories, and add (or remove, if
       --  Removed is True) them to list of source directories of the project.
@@ -5034,109 +4841,86 @@ package body Prj.Nmsc is
       procedure Find_Source_Dirs
         (From     : File_Name_Type;
          Location : Source_Ptr;
+         Rank     : Natural;
          Removed  : Boolean := False)
       is
          Directory : constant String := Get_Name_String (From);
-         Element   : String_Element;
+
+         procedure Add_To_Or_Remove_From_List
+           (Path_Id         : Name_Id;
+            Display_Path_Id : Name_Id);
+         --  When Removed = False, the directory Path_Id to the list of
+         --  source_dirs if not already in the list. When Removed = True,
+         --  removed directory Path_Id if in the list.
 
          procedure Recursive_Find_Dirs (Path : Name_Id);
          --  Find all the subdirectories (recursively) of Path and add them
          --  to the list of source directories of the project.
 
-         -------------------------
-         -- Recursive_Find_Dirs --
-         -------------------------
-
-         procedure Recursive_Find_Dirs (Path : Name_Id) is
-            Dir     : Dir_Type;
-            Name    : String (1 .. 250);
-            Last    : Natural;
-            List    : String_List_Id;
-            Prev    : String_List_Id;
-            Element : String_Element;
-            Found   : Boolean := False;
-
-            Non_Canonical_Path : Name_Id := No_Name;
-            Canonical_Path     : Name_Id := No_Name;
-
-            The_Path : constant String :=
-                         Normalize_Pathname
-                           (Get_Name_String (Path),
-                            Directory     => Current_Dir,
-                            Resolve_Links => Opt.Follow_Links_For_Dirs) &
-                         Directory_Separator;
-
-            The_Path_Last : constant Natural :=
-                              Compute_Directory_Last (The_Path);
+         --------------------------------
+         -- Add_To_Or_Remove_From_List --
+         --------------------------------
+
+         procedure Add_To_Or_Remove_From_List
+           (Path_Id         : Name_Id;
+            Display_Path_Id : Name_Id)
+         is
+            List       : String_List_Id;
+            Prev       : String_List_Id;
+            Rank_List  : Number_List_Index;
+            Prev_Rank  : Number_List_Index;
+            Element    : String_Element;
 
          begin
-            Name_Len := The_Path_Last - The_Path'First + 1;
-            Name_Buffer (1 .. Name_Len) :=
-              The_Path (The_Path'First .. The_Path_Last);
-            Non_Canonical_Path := Name_Find;
-            Canonical_Path :=
-              Name_Id (Canonical_Case_File_Name (Non_Canonical_Path));
-
-            --  To avoid processing the same directory several times, check
-            --  if the directory is already in Recursive_Dirs. If it is, then
-            --  there is nothing to do, just return. If it is not, put it there
-            --  and continue recursive processing.
-
-            if not Removed then
-               if Recursive_Dirs.Get (Visited, Canonical_Path) then
-                  return;
-               else
-                  Recursive_Dirs.Set (Visited, Canonical_Path, True);
-               end if;
-            end if;
-
-            --  Check if directory is already in list
-
-            List := Project.Source_Dirs;
-            Prev := Nil_String;
+            Prev      := Nil_String;
+            Prev_Rank := No_Number_List;
+            List      := Project.Source_Dirs;
+            Rank_List := Project.Source_Dir_Ranks;
             while List /= Nil_String loop
                Element := Data.Tree.String_Elements.Table (List);
-
-               if Element.Value /= No_Name then
-                  Found := Element.Value = Canonical_Path;
-                  exit when Found;
-               end if;
-
+               exit when Element.Value = Path_Id;
                Prev := List;
                List := Element.Next;
+               Prev_Rank := Rank_List;
+               Rank_List := Data.Tree.Number_Lists.Table (Prev_Rank).Next;
             end loop;
 
-            --  If directory is not already in list, put it there
+            --  The directory is in the list if List is not Nil_String
 
-            if (not Removed) and (not Found) then
+            if not Removed and then List = Nil_String then
                if Current_Verbosity = High then
-                  Write_Str  ("   ");
-                  Write_Line (The_Path (The_Path'First .. The_Path_Last));
+                  Write_Str  ("   Adding Source Dir=");
+                  Write_Line (Get_Name_String (Path_Id));
                end if;
 
                String_Element_Table.Increment_Last (Data.Tree.String_Elements);
                Element :=
-                 (Value         => Canonical_Path,
-                  Display_Value => Non_Canonical_Path,
+                 (Value         => Path_Id,
+                  Index         => 0,
+                  Display_Value => Display_Path_Id,
                   Location      => No_Location,
                   Flag          => False,
-                  Next          => Nil_String,
-                  Index         => 0);
+                  Next          => Nil_String);
 
-               --  Case of first source directory
+               Number_List_Table.Increment_Last (Data.Tree.Number_Lists);
 
                if Last_Source_Dir = Nil_String then
+
+                  --  This is the first source directory
+
                   Project.Source_Dirs :=
                     String_Element_Table.Last (Data.Tree.String_Elements);
-
-                  --  Here we already have source directories
+                  Project.Source_Dir_Ranks :=
+                    Number_List_Table.Last (Data.Tree.Number_Lists);
 
                else
-                  --  Link the previous last to the new one
+                  --  We already have source directories, link the previous
+                  --  last to the new one.
 
-                  Data.Tree.String_Elements.Table
-                    (Last_Source_Dir).Next :=
-                      String_Element_Table.Last (Data.Tree.String_Elements);
+                  Data.Tree.String_Elements.Table (Last_Source_Dir).Next :=
+                    String_Element_Table.Last (Data.Tree.String_Elements);
+                  Data.Tree.Number_Lists.Table (Last_Src_Dir_Rank).Next :=
+                    Number_List_Table.Last (Data.Tree.Number_Lists);
                end if;
 
                --  And register this source directory as the new last
@@ -5144,20 +4928,81 @@ package body Prj.Nmsc is
                Last_Source_Dir :=
                  String_Element_Table.Last (Data.Tree.String_Elements);
                Data.Tree.String_Elements.Table (Last_Source_Dir) := Element;
+               Last_Src_Dir_Rank :=
+                 Number_List_Table.Last (Data.Tree.Number_Lists);
+               Data.Tree.Number_Lists.Table (Last_Src_Dir_Rank) :=
+                 (Number => Rank, Next => No_Number_List);
+
+            elsif Removed and then List /= Nil_String then
+
+               --  Remove source dir, if present
 
-            elsif Removed and Found then
                if Prev = Nil_String then
                   Project.Source_Dirs :=
                     Data.Tree.String_Elements.Table (List).Next;
+                  Project.Source_Dir_Ranks :=
+                    Data.Tree.Number_Lists.Table (Rank_List).Next;
+
                else
                   Data.Tree.String_Elements.Table (Prev).Next :=
                     Data.Tree.String_Elements.Table (List).Next;
+                  Data.Tree.Number_Lists.Table (Prev_Rank).Next :=
+                    Data.Tree.Number_Lists.Table (Rank_List).Next;
+               end if;
+            end if;
+         end Add_To_Or_Remove_From_List;
+
+         -------------------------
+         -- Recursive_Find_Dirs --
+         -------------------------
+
+         procedure Recursive_Find_Dirs (Path : Name_Id) is
+            Dir  : Dir_Type;
+            Name : String (1 .. 250);
+            Last : Natural;
+
+            Non_Canonical_Path : Name_Id := No_Name;
+            Canonical_Path     : Name_Id := No_Name;
+
+            The_Path : constant String :=
+                         Normalize_Pathname
+                           (Get_Name_String (Path),
+                            Directory     =>
+                              Get_Name_String (Project.Directory.Display_Name),
+                            Resolve_Links => Opt.Follow_Links_For_Dirs) &
+                         Directory_Separator;
+
+            The_Path_Last : constant Natural :=
+                              Compute_Directory_Last (The_Path);
+
+         begin
+            Name_Len := The_Path_Last - The_Path'First + 1;
+            Name_Buffer (1 .. Name_Len) :=
+              The_Path (The_Path'First .. The_Path_Last);
+            Non_Canonical_Path := Name_Find;
+            Canonical_Path :=
+              Name_Id (Canonical_Case_File_Name (Non_Canonical_Path));
+
+            --  To avoid processing the same directory several times, check
+            --  if the directory is already in Recursive_Dirs. If it is, then
+            --  there is nothing to do, just return. If it is not, put it there
+            --  and continue recursive processing.
+
+            if not Removed then
+               if Recursive_Dirs.Get (Visited, Canonical_Path) then
+                  return;
+               else
+                  Recursive_Dirs.Set (Visited, Canonical_Path, True);
                end if;
             end if;
 
-            --  Now look for subdirectories. We do that even when this
-            --  directory is already in the list, because some of its
-            --  subdirectories may not be in the list yet.
+            Add_To_Or_Remove_From_List
+              (Path_Id         => Canonical_Path,
+               Display_Path_Id => Non_Canonical_Path);
+
+            --  Now look for subdirectories. Do that even when this directory
+            --  is already in the list, because some of its subdirectories may
+            --  not be in the list yet.
 
             Open (Dir, The_Path (The_Path'First .. The_Path_Last));
 
@@ -5177,15 +5022,18 @@ package body Prj.Nmsc is
 
                   declare
                      Path_Name : constant String :=
-                       Normalize_Pathname
-                         (Name      => Name (1 .. Last),
-                          Directory =>
-                            The_Path (The_Path'First .. The_Path_Last),
-                          Resolve_Links  => Opt.Follow_Links_For_Dirs,
-                          Case_Sensitive => True);
+                                   Normalize_Pathname
+                                     (Name           => Name (1 .. Last),
+                                      Directory      =>
+                                        The_Path
+                                          (The_Path'First .. The_Path_Last),
+                                      Resolve_Links  =>
+                                        Opt.Follow_Links_For_Dirs,
+                                      Case_Sensitive => True);
 
                   begin
                      if Is_Directory (Path_Name) then
+
                         --  We have found a new subdirectory, call self
 
                         Name_Len := Path_Name'Length;
@@ -5209,6 +5057,8 @@ package body Prj.Nmsc is
          if Current_Verbosity = High and then not Removed then
             Write_Str ("Find_Source_Dirs (""");
             Write_Str (Directory);
+            Write_Str (",");
+            Write_Str (Rank'Img);
             Write_Line (""")");
          end if;
 
@@ -5221,10 +5071,6 @@ package body Prj.Nmsc is
                        or else
                      Directory (Directory'Last - 2) = Directory_Separator)
          then
-            if not Removed then
-               Project.Known_Order_Of_Source_Dirs := False;
-            end if;
-
             Name_Len := Directory'Length - 3;
 
             if Name_Len = 0 then
@@ -5253,7 +5099,8 @@ package body Prj.Nmsc is
                                Directory =>
                                  Get_Name_String
                                    (Project.Directory.Display_Name),
-                               Resolve_Links  => False,
+                               Resolve_Links  =>
+                                 Opt.Follow_Links_For_Dirs,
                                Case_Sensitive => True);
 
             begin
@@ -5262,14 +5109,14 @@ package body Prj.Nmsc is
 
                   if Location = No_Location then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "{ is not a valid directory.",
-                        Project.Location, Data);
+                        Project.Location, Project);
                   else
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "{ is not a valid directory.",
-                        Location, Data);
+                        Location, Project);
                   end if;
 
                else
@@ -5295,8 +5142,6 @@ package body Prj.Nmsc is
          else
             declare
                Path_Name  : Path_Information;
-               List       : String_List_Id;
-               Prev       : String_List_Id;
                Dir_Exists : Boolean;
 
             begin
@@ -5313,20 +5158,28 @@ package body Prj.Nmsc is
 
                   if Location = No_Location then
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "{ is not a valid directory",
-                        Project.Location, Data);
+                        Project.Location, Project);
                   else
                      Error_Msg
-                       (Project,
+                       (Data.Flags,
                         "{ is not a valid directory",
-                        Location, Data);
+                        Location, Project);
                   end if;
 
                else
                   declare
-                     Path              : constant String :=
-                                           Get_Name_String (Path_Name.Name);
+                     Path : constant String :=
+                              Normalize_Pathname
+                                (Name           =>
+                                   Get_Name_String (Path_Name.Name),
+                                 Directory      =>
+                                   Get_Name_String (Project.Directory.Name),
+                                 Resolve_Links  => Opt.Follow_Links_For_Dirs,
+                                 Case_Sensitive => True) &
+                              Directory_Separator;
+
                      Last_Path         : constant Natural :=
                                            Compute_Directory_Last (Path);
                      Path_Id           : Name_Id;
@@ -5342,79 +5195,16 @@ package body Prj.Nmsc is
                      Name_Len := 0;
                      Add_Str_To_Name_Buffer (Path (Path'First .. Last_Path));
                      Path_Id := Name_Find;
+
                      Name_Len := 0;
                      Add_Str_To_Name_Buffer
                        (Display_Path
                           (Display_Path'First .. Last_Display_Path));
                      Display_Path_Id := Name_Find;
 
-                     if not Removed then
-
-                        --  As it is an existing directory, we add it to the
-                        --  list of directories.
-
-                        String_Element_Table.Increment_Last
-                          (Data.Tree.String_Elements);
-                        Element :=
-                          (Value         => Path_Id,
-                           Index         => 0,
-                           Display_Value => Display_Path_Id,
-                           Location      => No_Location,
-                           Flag          => False,
-                           Next          => Nil_String);
-
-                        if Last_Source_Dir = Nil_String then
-
-                           --  This is the first source directory
-
-                           Project.Source_Dirs := String_Element_Table.Last
-                             (Data.Tree.String_Elements);
-
-                        else
-                           --  We already have source directories, link the
-                           --  previous last to the new one.
-
-                           Data.Tree.String_Elements.Table
-                             (Last_Source_Dir).Next :=
-                             String_Element_Table.Last
-                               (Data.Tree.String_Elements);
-                        end if;
-
-                        --  And register this source directory as the new last
-
-                        Last_Source_Dir := String_Element_Table.Last
-                          (Data.Tree.String_Elements);
-                        Data.Tree.String_Elements.Table
-                          (Last_Source_Dir) := Element;
-
-                     else
-                        --  Remove source dir, if present
-
-                        Prev := Nil_String;
-
-                        --  Look for source dir in current list
-
-                        List := Project.Source_Dirs;
-                        while List /= Nil_String loop
-                           Element := Data.Tree.String_Elements.Table (List);
-                           exit when Element.Value = Path_Id;
-                           Prev := List;
-                           List := Element.Next;
-                        end loop;
-
-                        if List /= Nil_String then
-                           --  Source dir was found, remove it from the list
-
-                           if Prev = Nil_String then
-                              Project.Source_Dirs :=
-                                Data.Tree.String_Elements.Table (List).Next;
-
-                           else
-                              Data.Tree.String_Elements.Table (Prev).Next :=
-                                Data.Tree.String_Elements.Table (List).Next;
-                           end if;
-                        end if;
-                     end if;
+                     Add_To_Or_Remove_From_List
+                       (Path_Id         => Path_Id,
+                        Display_Path_Id => Display_Path_Id);
                   end;
                end if;
             end;
@@ -5436,7 +5226,7 @@ package body Prj.Nmsc is
       --  is no sources in the project.
 
       if (((not Source_Files.Default)
-           and then Source_Files.Values = Nil_String)
+             and then Source_Files.Values = Nil_String)
           or else
            ((not Source_Dirs.Default) and then Source_Dirs.Values = Nil_String)
               or else
@@ -5455,9 +5245,9 @@ package body Prj.Nmsc is
 
          if Name_Len = 0 then
             Error_Msg
-              (Project,
+              (Data.Flags,
                "Object_Dir cannot be empty",
-               Object_Dir.Location, Data);
+               Object_Dir.Location, Project);
 
          else
             --  We check that the specified object directory does exist.
@@ -5485,10 +5275,21 @@ package body Prj.Nmsc is
 
                Err_Vars.Error_Msg_File_1 :=
                  File_Name_Type (Object_Dir.Value);
-               Error_Msg
-                 (Project,
-                  "object directory { not found",
-                  Project.Location, Data);
+
+               case Data.Flags.Require_Obj_Dirs is
+                  when Error =>
+                     Error_Msg
+                       (Data.Flags,
+                        "object directory { not found",
+                        Project.Location, Project);
+                  when Warning =>
+                     Error_Msg
+                       (Data.Flags,
+                        "?object directory { not found",
+                        Project.Location, Project);
+                  when Silent =>
+                     null;
+               end case;
             end if;
          end if;
 
@@ -5529,9 +5330,9 @@ package body Prj.Nmsc is
 
          if Name_Len = 0 then
             Error_Msg
-              (Project,
+              (Data.Flags,
                "Exec_Dir cannot be empty",
-               Exec_Dir.Location, Data);
+               Exec_Dir.Location, Project);
 
          else
             --  We check that the specified exec directory does exist
@@ -5549,9 +5350,9 @@ package body Prj.Nmsc is
             if not Dir_Exists then
                Err_Vars.Error_Msg_File_1 := File_Name_Type (Exec_Dir.Value);
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "exec directory { not found",
-                  Project.Location, Data);
+                  Project.Location, Project);
             end if;
          end if;
       end if;
@@ -5581,9 +5382,9 @@ package body Prj.Nmsc is
 
          if Project.Qualifier = Standard then
             Error_Msg
-              (Project,
+              (Data.Flags,
                "a standard project cannot have no sources",
-               Source_Files.Location, Data);
+               Source_Files.Location, Project);
          end if;
 
       elsif Source_Dirs.Default then
@@ -5598,9 +5399,17 @@ package body Prj.Nmsc is
             Flag          => False,
             Next          => Nil_String,
             Index         => 0));
+
          Project.Source_Dirs :=
            String_Element_Table.Last (Data.Tree.String_Elements);
 
+         Number_List_Table.Append
+           (Data.Tree.Number_Lists,
+            (Number => 1, Next => No_Number_List));
+
+         Project.Source_Dir_Ranks :=
+           Number_List_Table.Last (Data.Tree.Number_Lists);
+
          if Current_Verbosity = High then
             Write_Attr
               ("Default source directory",
@@ -5610,9 +5419,9 @@ package body Prj.Nmsc is
       elsif Source_Dirs.Values = Nil_String then
          if Project.Qualifier = Standard then
             Error_Msg
-              (Project,
+              (Data.Flags,
                "a standard project cannot have no source directories",
-               Source_Dirs.Location, Data);
+               Source_Dirs.Location, Project);
          end if;
 
          Project.Source_Dirs := Nil_String;
@@ -5621,15 +5430,17 @@ package body Prj.Nmsc is
          declare
             Source_Dir : String_List_Id;
             Element    : String_Element;
-
+            Rank       : Natural;
          begin
             --  Process the source directories for each element of the list
 
             Source_Dir := Source_Dirs.Values;
+            Rank := 0;
             while Source_Dir /= Nil_String loop
                Element := Data.Tree.String_Elements.Table (Source_Dir);
+               Rank := Rank + 1;
                Find_Source_Dirs
-                 (File_Name_Type (Element.Value), Element.Location);
+                 (File_Name_Type (Element.Value), Element.Location, Rank);
                Source_Dir := Element.Next;
             end loop;
          end;
@@ -5651,6 +5462,7 @@ package body Prj.Nmsc is
                Find_Source_Dirs
                  (File_Name_Type (Element.Value),
                   Element.Location,
+                  0,
                   Removed => True);
                Source_Dir := Element.Next;
             end loop;
@@ -5708,9 +5520,9 @@ package body Prj.Nmsc is
 
       elsif Project.Library then
          Error_Msg
-           (Project,
+           (Data.Flags,
             "a library project file cannot have Main specified",
-            Mains.Location, Data);
+            Mains.Location, Project);
 
       else
          List := Mains.Values;
@@ -5719,9 +5531,9 @@ package body Prj.Nmsc is
 
             if Length_Of_Name (Elem.Value) = 0 then
                Error_Msg
-                 (Project,
+                 (Data.Flags,
                   "?a main cannot have an empty name",
-                  Elem.Location, Data);
+                  Elem.Location, Project);
                exit;
             end if;
 
@@ -5758,7 +5570,8 @@ package body Prj.Nmsc is
       Prj.Util.Open (File, Path);
 
       if not Prj.Util.Is_Valid (File) then
-         Error_Msg (Project.Project, "file does not exist", Location, Data);
+         Error_Msg
+           (Data.Flags, "file does not exist", Location, Project.Project);
 
       else
          --  Read the lines one by one
@@ -5782,9 +5595,9 @@ package body Prj.Nmsc is
                   if Line (J) = '/' or else Line (J) = Directory_Separator then
                      Error_Msg_File_1 := Source_Name;
                      Error_Msg
-                       (Project.Project,
+                       (Data.Flags,
                         "file name cannot include directory information ({)",
-                        Location, Data);
+                        Location, Project.Project);
                      exit;
                   end if;
                end loop;
@@ -5824,17 +5637,9 @@ package body Prj.Nmsc is
    is
       Filename : constant String  := Get_Name_String (File_Name);
       Last     : Integer          := Filename'Last;
-      Sep_Len  : constant Integer :=
-                   Integer (Length_Of_Name (Naming.Separate_Suffix));
-      Body_Len : constant Integer :=
-                   Integer (Length_Of_Name (Naming.Body_Suffix));
-      Spec_Len : constant Integer :=
-                   Integer (Length_Of_Name (Naming.Spec_Suffix));
-
-      Standard_GNAT : constant Boolean :=
-                        Naming.Spec_Suffix = Default_Ada_Spec_Suffix
-                          and then
-                        Naming.Body_Suffix = Default_Ada_Body_Suffix;
+      Sep_Len  : Integer;
+      Body_Len : Integer;
+      Spec_Len : Integer;
 
       Unit_Except : Unit_Exception;
       Masked      : Boolean  := False;
@@ -5843,6 +5648,13 @@ package body Prj.Nmsc is
       Unit := No_Name;
       Kind := Spec;
 
+      if Naming.Separate_Suffix = No_File
+        or else Naming.Body_Suffix = No_File
+        or else Naming.Spec_Suffix = No_File
+      then
+         return;
+      end if;
+
       if Naming.Dot_Replacement = No_File then
          if Current_Verbosity = High then
             Write_Line ("  No dot_replacement specified");
@@ -5851,6 +5663,10 @@ package body Prj.Nmsc is
          return;
       end if;
 
+      Sep_Len  := Integer (Length_Of_Name (Naming.Separate_Suffix));
+      Spec_Len := Integer (Length_Of_Name (Naming.Spec_Suffix));
+      Body_Len := Integer (Length_Of_Name (Naming.Body_Suffix));
+
       --  Choose the longest suffix that matches. If there are several matches,
       --  give priority to specs, then bodies, then separates.
 
@@ -5952,7 +5768,9 @@ package body Prj.Nmsc is
       --  In the standard GNAT naming scheme, check for special cases: children
       --  or separates of A, G, I or S, and run time sources.
 
-      if Standard_GNAT and then Name_Len >= 3 then
+      if Is_Standard_GNAT_Naming (Naming)
+        and then Name_Len >= 3
+      then
          declare
             S1 : constant Character := Name_Buffer (1);
             S2 : constant Character := Name_Buffer (2);
@@ -5981,10 +5799,9 @@ package body Prj.Nmsc is
 
                elsif S2 = '.' then
 
-                  --  If it is potentially a run time source, disable filling
-                  --  of the mapping file to avoid warnings.
+                  --  If it is potentially a run time source
 
-                  Set_Mapping_File_Initial_State_To_Empty (In_Tree);
+                  null;
                end if;
             end if;
          end;
@@ -6060,15 +5877,17 @@ package body Prj.Nmsc is
 
    begin
       if Suffix_Str'Length = 0 then
+
          --  Always valid
+
          return;
 
       elsif Index (Suffix_Str, ".") = 0 then
          Err_Vars.Error_Msg_File_1 := Suffix;
          Error_Msg
-           (Project,
+           (Data.Flags,
             "{ is illegal for " & Attribute_Name & ": must have a dot",
-            Location, Data);
+            Location, Project);
          return;
       end if;
 
@@ -6090,10 +5909,10 @@ package body Prj.Nmsc is
                if Is_Letter (Suffix_Str (Suffix_Str'First + 1)) then
                   Err_Vars.Error_Msg_File_1 := Suffix;
                   Error_Msg
-                    (Project,
+                    (Data.Flags,
                      "{ is illegal for " & Attribute_Name
                      & ": ambiguous prefix when Dot_Replacement is a dot",
-                     Location, Data);
+                     Location, Project);
                end if;
                return;
             end if;
@@ -6212,10 +6031,10 @@ package body Prj.Nmsc is
                   exception
                      when Use_Error =>
                         Error_Msg
-                          (Project,
+                          (Data.Flags,
                            "could not create " & Create &
                            " directory " & Full_Path_Name.all,
-                           Location, Data);
+                           Location, Project);
                   end;
                end if;
             end if;
@@ -6275,15 +6094,14 @@ package body Prj.Nmsc is
    ---------------------------
 
    procedure Find_Excluded_Sources
-     (Project   : in out Project_Processing_Data;
-      Data      : in out Tree_Processing_Data)
+     (Project : in out Project_Processing_Data;
+      Data    : in out Tree_Processing_Data)
    is
       Excluded_Source_List_File : constant Variable_Value :=
                                     Util.Value_Of
                                       (Name_Excluded_Source_List_File,
                                        Project.Project.Decl.Attributes,
                                        Data.Tree);
-
       Excluded_Sources          : Variable_Value := Util.Value_Of
                                     (Name_Excluded_Source_Files,
                                      Project.Project.Decl.Attributes,
@@ -6315,16 +6133,16 @@ package body Prj.Nmsc is
          if not Excluded_Source_List_File.Default then
             if Locally_Removed then
                Error_Msg
-                 (Project.Project,
+                 (Data.Flags,
                   "?both attributes Locally_Removed_Files and " &
                   "Excluded_Source_List_File are present",
-                  Excluded_Source_List_File.Location, Data);
+                  Excluded_Source_List_File.Location, Project.Project);
             else
                Error_Msg
-                 (Project.Project,
+                 (Data.Flags,
                   "?both attributes Excluded_Source_Files and " &
                   "Excluded_Source_List_File are present",
-                  Excluded_Source_List_File.Location, Data);
+                  Excluded_Source_List_File.Location, Project.Project);
             end if;
          end if;
 
@@ -6362,9 +6180,9 @@ package body Prj.Nmsc is
                Err_Vars.Error_Msg_File_1 :=
                  File_Name_Type (Excluded_Source_List_File.Value);
                Error_Msg
-                 (Project.Project,
+                 (Data.Flags,
                   "file with excluded sources { does not exist",
-                  Excluded_Source_List_File.Location, Data);
+                  Excluded_Source_List_File.Location, Project.Project);
 
             else
                --  Open the file
@@ -6373,7 +6191,8 @@ package body Prj.Nmsc is
 
                if not Prj.Util.Is_Valid (File) then
                   Error_Msg
-                    (Project.Project, "file does not exist", Location, Data);
+                    (Data.Flags, "file does not exist",
+                     Location, Project.Project);
                else
                   --  Read the lines one by one
 
@@ -6398,10 +6217,10 @@ package body Prj.Nmsc is
                            then
                               Error_Msg_File_1 := Name;
                               Error_Msg
-                                (Project.Project,
+                                (Data.Flags,
                                  "file name cannot include " &
                                  "directory information ({)",
-                                 Location, Data);
+                                 Location, Project.Project);
                               exit;
                            end if;
                         end loop;
@@ -6454,10 +6273,10 @@ package body Prj.Nmsc is
       if not Sources.Default then
          if not Source_List_File.Default then
             Error_Msg
-              (Project.Project,
+              (Data.Flags,
                "?both attributes source_files and " &
                "source_list_file are present",
-               Source_List_File.Location, Data);
+               Source_List_File.Location, Project.Project);
          end if;
 
          --  Sources is a list of file names
@@ -6506,10 +6325,10 @@ package body Prj.Nmsc is
                   then
                      Error_Msg_File_1 := Name;
                      Error_Msg
-                       (Project.Project,
+                       (Data.Flags,
                         "file name cannot include directory " &
                         "information ({)",
-                        Location, Data);
+                        Location, Project.Project);
                      exit;
                   end if;
                end loop;
@@ -6558,9 +6377,9 @@ package body Prj.Nmsc is
                Err_Vars.Error_Msg_File_1 :=
                  File_Name_Type (Source_List_File.Value);
                Error_Msg
-                 (Project.Project,
+                 (Data.Flags,
                   "file with sources { does not exist",
-                  Source_List_File.Location, Data);
+                  Source_List_File.Location, Project.Project);
 
             else
                Get_Sources_From_File
@@ -6582,9 +6401,7 @@ package body Prj.Nmsc is
          Data            => Data,
          For_All_Sources => Sources.Default and then Source_List_File.Default);
 
-      --  Check if all exceptions have been found. For Ada, it is an error if
-      --  an exception is not found. For other language, the source is simply
-      --  removed.
+      --  Check if all exceptions have been found
 
       declare
          Source : Source_Id;
@@ -6601,9 +6418,11 @@ package body Prj.Nmsc is
             then
                if Source.Unit /= No_Unit_Index then
 
-                  --  ??? Current limitation of gprbuild will display this
-                  --  error message for multi-unit source files, because not
-                  --  all instances of the file have had their path fully set.
+                  --  For multi-unit source files, source_id gets duplicated
+                  --  once for every unit. Only the first source_id got its
+                  --  full path set. So if it isn't set for that first one,
+                  --  the file wasn't found. Otherwise we need to update for
+                  --  units after the first one.
 
                   if Source.Index = 0
                     or else Source.Index = 1
@@ -6611,14 +6430,11 @@ package body Prj.Nmsc is
                      Error_Msg_Name_1 := Name_Id (Source.Display_File);
                      Error_Msg_Name_2 := Name_Id (Source.Unit.Name);
                      Error_Msg
-                       (Project.Project,
+                       (Data.Flags,
                         "source file %% for unit %% not found",
-                        No_Location, Data);
+                        No_Location, Project.Project);
 
                   else
-                     --  Set the full path information since we know it
-                     --  anyway
-
                      Source.Path := Files_Htable.Get
                        (Data.File_To_Source, Source.File).Path;
 
@@ -6660,16 +6476,16 @@ package body Prj.Nmsc is
 
                   if First_Error then
                      Error_Msg
-                       (Project.Project,
+                       (Data.Flags,
                         "source file { not found",
-                        NL.Location, Data);
+                        NL.Location, Project.Project);
                      First_Error := False;
 
                   else
                      Error_Msg
-                       (Project.Project,
+                       (Data.Flags,
                         "\source file { not found",
-                        NL.Location, Data);
+                        NL.Location, Project.Project);
                   end if;
                end if;
 
@@ -6684,21 +6500,14 @@ package body Prj.Nmsc is
    ----------------
 
    procedure Initialize
-     (Data                       : out Tree_Processing_Data;
-      Tree                       : Project_Tree_Ref;
-      Report_Error               : Put_Line_Access;
-      When_No_Sources            : Error_Warning;
-      Require_Sources_Other_Lang : Boolean := True;
-      Allow_Duplicate_Basenames  : Boolean := True;
-      Compiler_Driver_Mandatory  : Boolean := False) is
+     (Data  : out Tree_Processing_Data;
+      Tree  : Project_Tree_Ref;
+      Flags : Prj.Processing_Flags)
+   is
    begin
       Files_Htable.Reset (Data.File_To_Source);
-      Data.Tree                       := Tree;
-      Data.Require_Sources_Other_Lang := Require_Sources_Other_Lang;
-      Data.Report_Error               := Report_Error;
-      Data.When_No_Sources            := When_No_Sources;
-      Data.Allow_Duplicate_Basenames  := Allow_Duplicate_Basenames;
-      Data.Compiler_Driver_Mandatory  := Compiler_Driver_Mandatory;
+      Data.Tree  := Tree;
+      Data.Flags := Flags;
    end Initialize;
 
    ----------
@@ -6716,7 +6525,8 @@ package body Prj.Nmsc is
 
    procedure Initialize
      (Data    : in out Project_Processing_Data;
-      Project : Project_Id) is
+      Project : Project_Id)
+   is
    begin
       Data.Project := Project;
    end Initialize;
@@ -6730,7 +6540,6 @@ package body Prj.Nmsc is
       Source_Names_Htable.Reset      (Data.Source_Names);
       Unit_Exceptions_Htable.Reset   (Data.Unit_Exceptions);
       Excluded_Sources_Htable.Reset  (Data.Excluded);
-      Object_File_Names_Htable.Reset (Data.Object_Files);
    end Free;
 
    -------------------------------
@@ -6890,6 +6699,14 @@ package body Prj.Nmsc is
 
       Source.Kind := Kind;
 
+      if Current_Verbosity = High
+        and then Source.File /= No_File
+      then
+         Write_Line ("Override kind for "
+                     & Get_Name_String (Source.File)
+                     & " kind=" & Source.Kind'Img);
+      end if;
+
       if Source.Kind in Spec_Or_Body and then Source.Unit /= null then
          Source.Unit.File_Names (Source.Kind) := Source;
       end if;
@@ -6902,6 +6719,7 @@ package body Prj.Nmsc is
    procedure Check_File
      (Project           : in out Project_Processing_Data;
       Data              : in out Tree_Processing_Data;
+      Source_Dir_Rank   : Natural;
       Path              : Path_Name_Type;
       File_Name         : File_Name_Type;
       Display_File_Name : File_Name_Type;
@@ -6913,7 +6731,8 @@ package body Prj.Nmsc is
                            (Canonical_Case_File_Name (Name_Id (Path)));
 
       Name_Loc              : Name_Location :=
-        Source_Names_Htable.Get (Project.Source_Names, File_Name);
+                                Source_Names_Htable.Get
+                                  (Project.Source_Names, File_Name);
       Check_Name            : Boolean := False;
       Alternate_Languages   : Language_List;
       Language              : Language_Ptr;
@@ -6925,20 +6744,29 @@ package body Prj.Nmsc is
       Kind                  : Source_Kind := Spec;
 
    begin
+      if Current_Verbosity = High then
+         Write_Line ("Checking file:");
+         Write_Str ("   Path = ");
+         Write_Line (Get_Name_String (Path));
+         Write_Str ("   Rank =");
+         Write_Line (Source_Dir_Rank'Img);
+      end if;
+
       if Name_Loc = No_Name_Location then
          Check_Name := For_All_Sources;
 
       else
          if Name_Loc.Found then
+
             --  Check if it is OK to have the same file name in several
             --  source directories.
 
-            if not Project.Project.Known_Order_Of_Source_Dirs then
+            if Source_Dir_Rank = Name_Loc.Source.Source_Dir_Rank then
                Error_Msg_File_1 := File_Name;
                Error_Msg
-                 (Project.Project,
+                 (Data.Flags,
                   "{ is found in several source directories",
-                  Name_Loc.Location, Data);
+                  Name_Loc.Location, Project.Project);
             end if;
 
          else
@@ -6993,20 +6821,21 @@ package body Prj.Nmsc is
 
             --  A file name in a list must be a source of a language
 
-            if Get_Mode = Multi_Language then
-               if Name_Loc.Found then
-                  Error_Msg_File_1 := File_Name;
-                  Error_Msg
-                    (Project.Project,
-                     "language unknown for {",
-                     Name_Loc.Location, Data);
-               end if;
+            if Data.Flags.Error_On_Unknown_Language
+              and then Name_Loc.Found
+            then
+               Error_Msg_File_1 := File_Name;
+               Error_Msg
+                 (Data.Flags,
+                  "language unknown for {",
+                  Name_Loc.Location, Project.Project);
             end if;
 
          else
             Add_Source
               (Id                  => Source,
                Project             => Project.Project,
+               Source_Dir_Rank     => Source_Dir_Rank,
                Lang_Id             => Language,
                Kind                => Kind,
                Data                => Data,
@@ -7014,10 +6843,16 @@ package body Prj.Nmsc is
                File_Name           => File_Name,
                Display_File        => Display_File_Name,
                Unit                => Unit,
+               Locally_Removed     => Locally_Removed,
                Path                => (Canonical_Path, Path));
 
-            if Source /= No_Source then
-               Source.Locally_Removed := Locally_Removed;
+            --  If it is a source specified in a list, update the entry in
+            --  the Source_Names table.
+
+            if Name_Loc.Found and then Name_Loc.Source = No_Source then
+               Name_Loc.Source := Source;
+               Source_Names_Htable.Set
+                 (Project.Source_Names, File_Name, Name_Loc);
             end if;
          end if;
       end if;
@@ -7034,6 +6869,8 @@ package body Prj.Nmsc is
    is
       Source_Dir        : String_List_Id;
       Element           : String_Element;
+      Src_Dir_Rank      : Number_List_Index;
+      Num_Nod           : Number_Node;
       Dir               : Dir_Type;
       Name              : String (1 .. 1_000);
       Last              : Natural;
@@ -7048,12 +6885,21 @@ package body Prj.Nmsc is
       --  Loop through subdirectories
 
       Source_Dir := Project.Project.Source_Dirs;
+      Src_Dir_Rank := Project.Project.Source_Dir_Ranks;
       while Source_Dir /= Nil_String loop
          begin
+            Num_Nod := Data.Tree.Number_Lists.Table (Src_Dir_Rank);
             Element := Data.Tree.String_Elements.Table (Source_Dir);
+
             if Element.Value /= No_Name then
                Get_Name_String (Element.Display_Value);
 
+               if Current_Verbosity = High then
+                  Write_Str ("Directory: ");
+                  Write_Str (Name_Buffer (1 .. Name_Len));
+                  Write_Line (Num_Nod.Number'Img);
+               end if;
+
                declare
                   Source_Directory : constant String :=
                                        Name_Buffer (1 .. Name_Len) &
@@ -7077,12 +6923,15 @@ package body Prj.Nmsc is
 
                      exit when Last = 0;
 
-                     --  ??? Duplicate system call here, we just did a a
-                     --  similar one. Maybe Ada.Directories would be more
-                     --  appropriate here.
+                     --  In fast project loading mode (without -eL), the user
+                     --  guarantees that no directory has a name which is a
+                     --  valid source name, so we can avoid doing a system call
+                     --  here. This provides a very significant speed up on
+                     --  slow file systems (remote files for instance).
 
-                     if Is_Regular_File
-                          (Source_Directory & Name (1 .. Last))
+                     if not Opt.Follow_Links_For_Files
+                       or else Is_Regular_File
+                                 (Source_Directory & Name (1 .. Last))
                      then
                         if Current_Verbosity = High then
                            Write_Str  ("   Checking ");
@@ -7140,7 +6989,7 @@ package body Prj.Nmsc is
                                  --  still need to add it to the list: if we
                                  --  don't, the file will not appear in the
                                  --  mapping file and will cause the compiler
-                                 --  to fail
+                                 --  to fail.
 
                                  To_Remove := True;
                               end if;
@@ -7148,6 +6997,7 @@ package body Prj.Nmsc is
 
                            Check_File
                              (Project           => Project,
+                              Source_Dir_Rank   => Num_Nod.Number,
                               Data              => Data,
                               Path              => Path,
                               File_Name         => File_Name,
@@ -7168,6 +7018,7 @@ package body Prj.Nmsc is
          end;
 
          Source_Dir := Element.Next;
+         Src_Dir_Rank := Num_Nod.Next;
       end loop;
 
       if Current_Verbosity = High then
@@ -7180,8 +7031,8 @@ package body Prj.Nmsc is
    ----------------------------
 
    procedure Load_Naming_Exceptions
-     (Project  : in out Project_Processing_Data;
-      Data     : in out Tree_Processing_Data)
+     (Project : in out Project_Processing_Data;
+      Data    : in out Tree_Processing_Data)
    is
       Source : Source_Id;
       Iter   : Source_Iterator;
@@ -7195,13 +7046,13 @@ package body Prj.Nmsc is
          --  An excluded file cannot also be an exception file name
 
          if Excluded_Sources_Htable.Get (Project.Excluded, Source.File) /=
-           No_File_Found
+                                                                 No_File_Found
          then
             Error_Msg_File_1 := Source.File;
             Error_Msg
-              (Project.Project,
+              (Data.Flags,
                "{ cannot be both excluded and an exception file name",
-               No_Location, Data);
+               No_Location, Project.Project);
          end if;
 
          if Current_Verbosity = High then
@@ -7214,10 +7065,10 @@ package body Prj.Nmsc is
            (Project.Source_Names,
             K => Source.File,
             E => Name_Location'
-              (Name     => Source.File,
-               Location => No_Location,
-               Source   => Source,
-               Found    => False));
+                  (Name     => Source.File,
+                   Location => No_Location,
+                   Source   => Source,
+                   Found    => False));
 
          --  If this is an Ada exception, record in table Unit_Exceptions
 
@@ -7253,15 +7104,49 @@ package body Prj.Nmsc is
      (Project : in out Project_Processing_Data;
       Data    : in out Tree_Processing_Data)
    is
-      Iter     : Source_Iterator;
-      Src      : Source_Id;
+      Object_Files : Object_File_Names_Htable.Instance;
+      Iter : Source_Iterator;
+      Src  : Source_Id;
+
+      procedure Check_Object (Src : Source_Id);
+      --  Check if object file name of Src is already used in the project tree,
+      --  and report an error if so.
 
-      procedure Process_Sources_In_Multi_Language_Mode;
-      --  Find all source files when in multi language mode
+      procedure Check_Object_Files;
+      --  Check that no two sources of this project have the same object file
 
       procedure Mark_Excluded_Sources;
       --  Mark as such the sources that are declared as excluded
 
+      ------------------
+      -- Check_Object --
+      ------------------
+
+      procedure Check_Object (Src : Source_Id) is
+         Source : Source_Id;
+
+      begin
+         Source := Object_File_Names_Htable.Get (Object_Files, Src.Object);
+
+         --  We cannot just check on "Source /= Src", since we might have
+         --  two different entries for the same file (and since that's
+         --  the same file it is expected that it has the same object)
+
+         if Source /= No_Source
+           and then Source.Path /= Src.Path
+         then
+            Error_Msg_File_1 := Src.File;
+            Error_Msg_File_2 := Source.File;
+            Error_Msg
+              (Data.Flags,
+               "{ and { have the same object file name",
+               No_Location, Project.Project);
+
+         else
+            Object_File_Names_Htable.Set (Object_Files, Src.Object, Src);
+         end if;
+      end Check_Object;
+
       ---------------------------
       -- Mark_Excluded_Sources --
       ---------------------------
@@ -7270,6 +7155,7 @@ package body Prj.Nmsc is
          Source   : Source_Id := No_Source;
          Excluded : File_Found;
          Proj     : Project_Id;
+
       begin
          --  Minor optimization: if there are no excluded files, no need to
          --  traverse the list of sources. We cannot however also check whether
@@ -7278,7 +7164,7 @@ package body Prj.Nmsc is
          --  them in any case.
 
          if Excluded_Sources_Htable.Get_First (Project.Excluded) /=
-           No_File_Found
+                                                             No_File_Found
          then
             Proj := Project.Project;
             while Proj /= No_Project loop
@@ -7314,7 +7200,6 @@ package body Prj.Nmsc is
          --  the source file
 
          Excluded := Excluded_Sources_Htable.Get_First (Project.Excluded);
-
          while Excluded /= No_File_Found loop
             if not Excluded.Found then
 
@@ -7331,13 +7216,13 @@ package body Prj.Nmsc is
 
                if Src = No_Source then
                   Error_Msg
-                    (Project.Project,
-                     "unknown file {", Excluded.Location, Data);
+                    (Data.Flags,
+                     "unknown file {", Excluded.Location, Project.Project);
                else
                   Error_Msg
-                    (Project.Project,
+                    (Data.Flags,
                      "cannot remove a source from an imported project: {",
-                     Excluded.Location, Data);
+                     Excluded.Location, Project.Project);
                end if;
             end if;
 
@@ -7345,125 +7230,78 @@ package body Prj.Nmsc is
          end loop;
       end Mark_Excluded_Sources;
 
-      --------------------------------------------
-      -- Process_Sources_In_Multi_Language_Mode --
-      --------------------------------------------
+      ------------------------
+      -- Check_Object_Files --
+      ------------------------
 
-      procedure Process_Sources_In_Multi_Language_Mode is
-         Iter : Source_Iterator;
+      procedure Check_Object_Files is
+         Iter    : Source_Iterator;
+         Src_Id  : Source_Id;
+         Src_Ind : Source_File_Index;
 
       begin
-         --  Check that two sources of this project do not have the same object
-         --  file name.
-
-         Check_Object_File_Names : declare
-            Src_Id      : Source_Id;
-
-            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.
-
-            ------------------
-            -- Check_Object --
-            ------------------
-
-            procedure Check_Object (Src : Source_Id) is
-               Source : Source_Id;
-            begin
-               Source := Object_File_Names_Htable.Get
-                 (Project.Object_Files, Src.Object);
+         Iter := For_Each_Source (Data.Tree);
+         loop
+            Src_Id := Prj.Element (Iter);
+            exit when Src_Id = No_Source;
 
-               if Source /= No_Source
-                 and then Source = Src
-               then
-                  Error_Msg_File_1 := Src.File;
-                  Error_Msg_File_2 := Source.File;
-                  Error_Msg
-                    (Project.Project,
-                     "{ and { have the same object file name",
-                     No_Location, Data);
+            if Is_Compilable (Src_Id)
+              and then Src_Id.Language.Config.Object_Generated
+              and then Is_Extending (Project.Project, Src_Id.Project)
+            then
+               if Src_Id.Unit = No_Unit_Index then
+                  if Src_Id.Kind = Impl then
+                     Check_Object (Src_Id);
+                  end if;
 
                else
-                  Object_File_Names_Htable.Set
-                    (Project.Object_Files, Src.Object, Src);
-               end if;
-            end Check_Object;
-
-         --  Start of processing for Check_Object_File_Names
-
-         begin
-            Iter := For_Each_Source (Data.Tree);
-            loop
-               Src_Id := Prj.Element (Iter);
-               exit when Src_Id = No_Source;
+                  case Src_Id.Kind is
+                     when Spec =>
+                        if Other_Part (Src_Id) = No_Source then
+                           Check_Object (Src_Id);
+                        end if;
 
-               if Is_Compilable (Src_Id)
-                 and then Src_Id.Language.Config.Object_Generated
-                 and then Is_Extending (Project.Project, Src_Id.Project)
-               then
-                  if Src_Id.Unit = No_Unit_Index 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 Other_Part (Src_Id) = No_Source then
-                              Check_Object (Src_Id);
-                           end if;
+                     when Impl =>
+                        if Other_Part (Src_Id) /= No_Source then
+                           Check_Object (Src_Id);
 
-                        when Sep =>
-                           null;
+                        else
+                           --  Check if it is a subunit
 
-                        when Impl =>
-                           if Other_Part (Src_Id) /= No_Source then
-                              Check_Object (Src_Id);
+                           Src_Ind :=
+                             Sinput.P.Load_Project_File
+                               (Get_Name_String (Src_Id.Path.Name));
 
+                           if Sinput.P.Source_File_Is_Subunit (Src_Ind) then
+                              Override_Kind (Src_Id, Sep);
                            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
-                                    Override_Kind (Src_Id, Sep);
-                                 else
-                                    Check_Object (Src_Id);
-                                 end if;
-                              end;
+                              Check_Object (Src_Id);
                            end if;
-                     end case;
-                  end if;
+                        end if;
+                  end case;
                end if;
+            end if;
 
-               Next (Iter);
-            end loop;
-         end Check_Object_File_Names;
-      end Process_Sources_In_Multi_Language_Mode;
+            Next (Iter);
+         end loop;
+      end Check_Object_Files;
 
    --  Start of processing for Look_For_Sources
 
    begin
       Find_Excluded_Sources (Project, Data);
 
-      if (Get_Mode = Ada_Only
-          and then Is_A_Language (Project.Project, Name_Ada))
-        or else (Get_Mode = Multi_Language
-                  and then Project.Project.Languages /= No_Language_Index)
-      then
+      if Project.Project.Languages /= No_Language_Index then
          Load_Naming_Exceptions (Project, Data);
          Find_Sources (Project, Data);
          Mark_Excluded_Sources;
-
-         Process_Sources_In_Multi_Language_Mode;
+         Check_Object_Files;
       end if;
+
+      Object_File_Names_Htable.Reset (Object_Files);
    end Look_For_Sources;
 
    ------------------
@@ -7510,7 +7348,13 @@ package body Prj.Nmsc is
    begin
       if Current_Verbosity = High then
          Write_Str ("Removing source ");
-         Write_Line (Get_Name_String (Id.File) & " at" & Id.Index'Img);
+         Write_Str (Get_Name_String (Id.File));
+
+         if Id.Index /= 0 then
+            Write_Str (" at" & Id.Index'Img);
+         end if;
+
+         Write_Eol;
       end if;
 
       if Replaced_By /= No_Source then
@@ -7554,7 +7398,7 @@ package body Prj.Nmsc is
       Continuation : Boolean := False)
    is
    begin
-      case Data.When_No_Sources is
+      case Data.Flags.When_No_Sources is
          when Silent =>
             null;
 
@@ -7566,12 +7410,12 @@ package body Prj.Nmsc is
                        " sources in this project";
 
             begin
-               Error_Msg_Warn := Data.When_No_Sources = Warning;
+               Error_Msg_Warn := Data.Flags.When_No_Sources = Warning;
 
                if Continuation then
-                  Error_Msg (Project, "\" & Msg, Location, Data);
+                  Error_Msg (Data.Flags, "\" & Msg, Location, Project);
                else
-                  Error_Msg (Project, Msg, Location, Data);
+                  Error_Msg (Data.Flags, Msg, Location, Project);
                end if;
             end;
       end case;
@@ -7601,4 +7445,49 @@ package body Prj.Nmsc is
 
       Write_Line ("end Source_Dirs.");
    end Show_Source_Dirs;
+
+   ---------------------------
+   -- Process_Naming_Scheme --
+   ---------------------------
+
+   procedure Process_Naming_Scheme
+     (Tree         : Project_Tree_Ref;
+      Root_Project : Project_Id;
+      Flags        : Processing_Flags)
+   is
+      procedure Recursive_Check
+        (Project : Project_Id;
+         Data    : in out Tree_Processing_Data);
+      --  Check_Naming_Scheme for the project
+
+      ---------------------
+      -- Recursive_Check --
+      ---------------------
+
+      procedure Recursive_Check
+        (Project : Project_Id;
+         Data    : in out Tree_Processing_Data)
+      is
+      begin
+         if Verbose_Mode then
+            Write_Str ("Processing_Naming_Scheme for project """);
+            Write_Str (Get_Name_String (Project.Name));
+            Write_Line ("""");
+         end if;
+
+         Prj.Nmsc.Check (Project, Data);
+      end Recursive_Check;
+
+      procedure Check_All_Projects is new
+        For_Every_Project_Imported (Tree_Processing_Data, Recursive_Check);
+
+      Data : Tree_Processing_Data;
+
+   --  Start of processing for Process_Naming_Scheme
+   begin
+      Initialize (Data, Tree => Tree, Flags => Flags);
+      Check_All_Projects (Root_Project, Data, Imported_First => True);
+      Free (Data);
+   end Process_Naming_Scheme;
+
 end Prj.Nmsc;