OSDN Git Service

2010-06-18 Thomas Quinot <quinot@adacore.com>
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Jun 2010 10:07:36 +0000 (10:07 +0000)
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Jun 2010 10:07:36 +0000 (10:07 +0000)
* g-socket.adb, g-socket.ads (Null_Selector): New object.

2010-06-18  Pascal Obry  <obry@adacore.com>

* gnat_ugn.texi: Minor clarification.

2010-06-18  Emmanuel Briot  <briot@adacore.com>

* prj-nmsc.adb (Find_Source_Dirs): Minor refactoring to avoid duplicate
code when using the project dir as the source dir.
(Search_Directories): use the normalized name for the source directory,
where symbolic names have potentially been resolved.

2010-06-18  Robert Dewar  <dewar@adacore.com>

* exp_ch4.adb (Expand_N_Conditional_Expression): Clear Actions field
when we create N_Expression_With_Actions node.
(Expand_Short_Circuit): Ditto.

2010-06-18  Robert Dewar  <dewar@adacore.com>

* exp_util.adb: Minor reformatting.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160975 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ada/ChangeLog
gcc/ada/exp_ch4.adb
gcc/ada/exp_util.adb
gcc/ada/g-socket.adb
gcc/ada/g-socket.ads
gcc/ada/gnat_ugn.texi
gcc/ada/prj-nmsc.adb

index e48bac3..bb99ab4 100644 (file)
@@ -1,5 +1,30 @@
 2010-06-18  Thomas Quinot  <quinot@adacore.com>
 
+       * g-socket.adb, g-socket.ads (Null_Selector): New object.
+
+2010-06-18  Pascal Obry  <obry@adacore.com>
+
+       * gnat_ugn.texi: Minor clarification.
+
+2010-06-18  Emmanuel Briot  <briot@adacore.com>
+
+       * prj-nmsc.adb (Find_Source_Dirs): Minor refactoring to avoid duplicate
+       code when using the project dir as the source dir.
+       (Search_Directories): use the normalized name for the source directory,
+       where symbolic names have potentially been resolved.
+
+2010-06-18  Robert Dewar  <dewar@adacore.com>
+
+       * exp_ch4.adb (Expand_N_Conditional_Expression): Clear Actions field
+       when we create N_Expression_With_Actions node.
+       (Expand_Short_Circuit): Ditto.
+
+2010-06-18  Robert Dewar  <dewar@adacore.com>
+
+       * exp_util.adb: Minor reformatting.
+
+2010-06-18  Thomas Quinot  <quinot@adacore.com>
+
        * types.ads: Clean up obsolete comments
        * tbuild.adb: Minor reformatting.
        * exp_ch5.adb, sem_intr.adb, sem_ch10.adb, rtsfind.adb, s-shasto.adb,
index 9a67fa9..96f3d27 100644 (file)
@@ -4111,6 +4111,7 @@ package body Exp_Ch4 is
                  Make_Expression_With_Actions (Sloc (Thenx),
                    Actions    => Then_Actions (N),
                    Expression => Relocate_Node (Thenx)));
+               Set_Then_Actions (N, No_List);
                Analyze_And_Resolve (Thenx, Typ);
             end if;
 
@@ -4119,6 +4120,7 @@ package body Exp_Ch4 is
                  Make_Expression_With_Actions (Sloc (Elsex),
                    Actions    => Else_Actions (N),
                    Expression => Relocate_Node (Elsex)));
+               Set_Else_Actions (N, No_List);
                Analyze_And_Resolve (Elsex, Typ);
             end if;
 
@@ -9044,6 +9046,7 @@ package body Exp_Ch4 is
               Make_Expression_With_Actions (LocR,
                 Expression => Relocate_Node (Right),
                 Actions    => Actlist));
+            Set_Actions (N, No_List);
             Analyze_And_Resolve (Right, Standard_Boolean);
          end if;
 
index 95036b9..66a1b77 100644 (file)
@@ -4685,7 +4685,7 @@ package body Exp_Util is
 
       --  If it is a scalar type and we need to capture the value, just make
       --  a copy. Likewise for a function call, an attribute reference, an
-      --  allocator or an operator. And if we have a volatile reference and
+      --  allocator, or an operator. And if we have a volatile reference and
       --  Name_Req is not set (see comments above for Side_Effect_Free).
 
       if Is_Elementary_Type (Exp_Type)
index e391f80..b75c525 100644 (file)
@@ -273,7 +273,8 @@ package body GNAT.Sockets is
 
    function Is_Open (S : Selector_Type) return Boolean;
    --  Return True for an "open" Selector_Type object, i.e. one for which
-   --  Create_Selector has been called and Close_Selector has not been called.
+   --  Create_Selector has been called and Close_Selector has not been called,
+   --  or the null selector.
 
    ---------
    -- "+" --
@@ -294,6 +295,10 @@ package body GNAT.Sockets is
    begin
       if not Is_Open (Selector) then
          raise Program_Error with "closed selector";
+
+      elsif Selector.Is_Null then
+         raise Program_Error with "null selector";
+
       end if;
 
       --  Send one byte to unblock select system call
@@ -491,7 +496,7 @@ package body GNAT.Sockets is
    is
       Res  : C.int;
       Last : C.int;
-      RSig : constant Socket_Type := Selector.R_Sig_Socket;
+      RSig : Socket_Type := No_Socket;
       TVal : aliased Timeval;
       TPtr : Timeval_Access;
 
@@ -511,9 +516,12 @@ package body GNAT.Sockets is
          TPtr := TVal'Unchecked_Access;
       end if;
 
-      --  Add read signalling socket
+      --  Add read signalling socket, if present
 
-      Set (R_Socket_Set, RSig);
+      if not Selector.Is_Null then
+         RSig := Selector.R_Sig_Socket;
+         Set (R_Socket_Set, RSig);
+      end if;
 
       Last := C.int'Max (C.int'Max (C.int (R_Socket_Set.Last),
                                     C.int (W_Socket_Set.Last)),
@@ -540,7 +548,7 @@ package body GNAT.Sockets is
       --  If Select was resumed because of read signalling socket, read this
       --  data and remove socket from set.
 
-      if Is_Set (R_Socket_Set, RSig) then
+      if RSig /= No_Socket and then Is_Set (R_Socket_Set, RSig) then
          Clear (R_Socket_Set, RSig);
 
          Res := Signalling_Fds.Read (C.int (RSig));
@@ -585,10 +593,9 @@ package body GNAT.Sockets is
 
    procedure Close_Selector (Selector : in out Selector_Type) is
    begin
-      if not Is_Open (Selector) then
-
-         --  Selector already in closed state: nothing to do
+      --  Nothing to do if selector already in closed state
 
+      if Selector.Is_Null or else not Is_Open (Selector) then
          return;
       end if;
 
@@ -1425,14 +1432,19 @@ package body GNAT.Sockets is
 
    function Is_Open (S : Selector_Type) return Boolean is
    begin
-      --  Either both controlling socket descriptors are valid (case of an
-      --  open selector) or neither (case of a closed selector).
+      if S.Is_Null then
+         return True;
+
+      else
+         --  Either both controlling socket descriptors are valid (case of an
+         --  open selector) or neither (case of a closed selector).
 
-      pragma Assert ((S.R_Sig_Socket /= No_Socket)
-                       =
-                     (S.W_Sig_Socket /= No_Socket));
+         pragma Assert ((S.R_Sig_Socket /= No_Socket)
+                          =
+                        (S.W_Sig_Socket /= No_Socket));
 
-      return S.R_Sig_Socket /= No_Socket;
+         return S.R_Sig_Socket /= No_Socket;
+      end if;
    end Is_Open;
 
    ------------
index cfb8da5..55330bd 100644 (file)
@@ -422,6 +422,11 @@ package GNAT.Sockets is
    type Selector_Access is access all Selector_Type;
    --  Selector objects are used to wait for i/o events to occur on sockets
 
+   Null_Selector : constant Selector_Type;
+   --  The Null_Selector can be used in place of a normal selector without
+   --  having to call Create_Selector if the use of Abort_Selector is not
+   --  required.
+
    --  Timeval_Duration is a subtype of Standard.Duration because the full
    --  range of Standard.Duration cannot be represented in the equivalent C
    --  structure. Moreover, negative values are not allowed to avoid system
@@ -1067,7 +1072,7 @@ package GNAT.Sockets is
    --  the situation where a change to the monitored sockets set must be made.
 
    procedure Create_Selector (Selector : out Selector_Type);
-   --  Create a new selector
+   --  Initialize (open) a new selector
 
    procedure Close_Selector (Selector : in out Selector_Type);
    --  Close Selector and all internal descriptors associated; deallocate any
@@ -1110,7 +1115,8 @@ package GNAT.Sockets is
    --  different objects.
 
    procedure Abort_Selector (Selector : Selector_Type);
-   --  Send an abort signal to the selector
+   --  Send an abort signal to the selector. The Selector may not be the
+   --  Null_Selector.
 
    type Fd_Set is private;
    --  ??? This type must not be used directly, it needs to be visible because
@@ -1126,14 +1132,28 @@ private
    type Socket_Type is new Integer;
    No_Socket : constant Socket_Type := -1;
 
-   type Selector_Type is limited record
-      R_Sig_Socket : Socket_Type := No_Socket;
-      W_Sig_Socket : Socket_Type := No_Socket;
-      --  Signalling sockets used to abort a select operation
+   --  A selector is either a null selector, which is always "open" and can
+   --  never be aborted, or a regular selector, which is created "closed",
+   --  becomes "open" when Create_Selector is called, and "closed" again when
+   --  Close_Selector is called.
+
+   type Selector_Type (Is_Null : Boolean := False) is limited record
+      case Is_Null is
+         when True =>
+            null;
+
+         when False =>
+            R_Sig_Socket : Socket_Type := No_Socket;
+            W_Sig_Socket : Socket_Type := No_Socket;
+            --  Signalling sockets used to abort a select operation
+
+      end case;
    end record;
 
    pragma Volatile (Selector_Type);
 
+   Null_Selector : constant Selector_Type := (Is_Null => True);
+
    type Fd_Set is
      new System.Storage_Elements.Storage_Array (1 .. SOSC.SIZEOF_fd_set);
    for Fd_Set'Alignment use Interfaces.C.long'Alignment;
index 0681dea..4e32b1b 100644 (file)
@@ -11549,7 +11549,8 @@ regular files.
 
 @noindent
 One or several Naming Patterns may be given as arguments to @code{gnatname}.
-Each Naming Pattern is enclosed between double quotes.
+Each Naming Pattern is enclosed between double quotes (or single
+quotes on Windows).
 A Naming Pattern is a regular expression similar to the wildcard patterns
 used in file names by the Unix shells or the DOS prompt.
 
index ea3ae29..a3f64d0 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 2000-2009, Free Software Foundation, Inc.         --
+--          Copyright (C) 2000-2010, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -4790,7 +4790,7 @@ package body Prj.Nmsc is
         (Header_Num => Header_Num,
          Element    => Boolean,
          No_Element => False,
-         Key        => Name_Id,
+         Key        => Path_Name_Type,
          Hash       => Hash,
          Equal      => "=");
       --  Hash table stores recursive source directories, to avoid looking
@@ -4837,123 +4837,127 @@ package body Prj.Nmsc is
       --  Find one or several source directories, and add (or remove, if
       --  Removed is True) them to list of source directories of the project.
 
-      ----------------------
-      -- Find_Source_Dirs --
-      ----------------------
-
-      procedure Find_Source_Dirs
-        (From     : File_Name_Type;
-         Location : Source_Ptr;
-         Rank     : Natural;
-         Removed  : Boolean := False)
+      procedure Add_To_Or_Remove_From_Source_Dirs
+        (Path_Id         : Path_Name_Type;
+         Display_Path_Id : Path_Name_Type;
+         Rank            : Natural;
+         Removed         : Boolean);
+      --  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.
+
+      ---------------------------------------
+      -- Add_To_Or_Remove_From_Source_Dirs --
+      ---------------------------------------
+
+      procedure Add_To_Or_Remove_From_Source_Dirs
+        (Path_Id         : Path_Name_Type;
+         Display_Path_Id : Path_Name_Type;
+         Rank            : Natural;
+         Removed         : Boolean)
       is
-         Directory : constant String := Get_Name_String (From);
+         List       : String_List_Id;
+         Prev       : String_List_Id;
+         Rank_List  : Number_List_Index;
+         Prev_Rank  : Number_List_Index;
+         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.
+      begin
+         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);
+            exit when Element.Value = Name_Id (Path_Id);
+            Prev := List;
+            List := Element.Next;
+            Prev_Rank := Rank_List;
+            Rank_List := Data.Tree.Number_Lists.Table (Prev_Rank).Next;
+         end loop;
 
-         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.
+         --  The directory is in the list if List is not Nil_String
 
-         --------------------------------
-         -- 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;
+         if not Removed and then List = Nil_String then
+            if Current_Verbosity = High then
+               Write_Str  ("   Adding Source Dir=");
+               Write_Line (Get_Name_String (Path_Id));
+            end if;
 
-         begin
-            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);
-               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;
+            String_Element_Table.Increment_Last (Data.Tree.String_Elements);
+            Element :=
+              (Value         => Name_Id (Path_Id),
+               Index         => 0,
+               Display_Value => Name_Id (Display_Path_Id),
+               Location      => No_Location,
+               Flag          => False,
+               Next          => Nil_String);
 
-            --  The directory is in the list if List is not Nil_String
+            Number_List_Table.Increment_Last (Data.Tree.Number_Lists);
 
-            if not Removed and then List = Nil_String then
-               if Current_Verbosity = High then
-                  Write_Str  ("   Adding Source Dir=");
-                  Write_Line (Get_Name_String (Path_Id));
-               end if;
+            if Last_Source_Dir = Nil_String then
 
-               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);
+               --  This is the first source directory
 
-               Number_List_Table.Increment_Last (Data.Tree.Number_Lists);
+               Project.Source_Dirs :=
+                 String_Element_Table.Last (Data.Tree.String_Elements);
+               Project.Source_Dir_Ranks :=
+                 Number_List_Table.Last (Data.Tree.Number_Lists);
 
-               if Last_Source_Dir = Nil_String then
+            else
+               --  We already have source directories, link the previous
+               --  last to the new one.
 
-                  --  This is the first source directory
+               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;
 
-                  Project.Source_Dirs :=
-                    String_Element_Table.Last (Data.Tree.String_Elements);
-                  Project.Source_Dir_Ranks :=
-                    Number_List_Table.Last (Data.Tree.Number_Lists);
+            --  And register this source directory as the new last
 
-               else
-                  --  We already have source directories, link the previous
-                  --  last to the new one.
+            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);
 
-                  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;
+         elsif Removed and then List /= Nil_String then
 
-               --  And register this source directory as the new last
+            --  Remove source dir, if present
 
-               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);
+            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;
 
-            elsif Removed and then List /= Nil_String then
+            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_Source_Dirs;
 
-               --  Remove source dir, if present
+      ----------------------
+      -- Find_Source_Dirs --
+      ----------------------
 
-               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;
+      procedure Find_Source_Dirs
+        (From     : File_Name_Type;
+         Location : Source_Ptr;
+         Rank     : Natural;
+         Removed  : Boolean := False)
+      is
+         Directory : constant String := Get_Name_String (From);
 
-               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;
+         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 --
@@ -4964,8 +4968,8 @@ package body Prj.Nmsc is
             Name : String (1 .. 250);
             Last : Natural;
 
-            Non_Canonical_Path : Name_Id := No_Name;
-            Canonical_Path     : Name_Id := No_Name;
+            Non_Canonical_Path : Path_Name_Type := No_Path;
+            Canonical_Path     : Path_Name_Type := No_Path;
 
             The_Path : constant String :=
                          Normalize_Pathname
@@ -4984,7 +4988,8 @@ package body Prj.Nmsc is
               The_Path (The_Path'First .. The_Path_Last);
             Non_Canonical_Path := Name_Find;
             Canonical_Path :=
-              Name_Id (Canonical_Case_File_Name (Non_Canonical_Path));
+              Path_Name_Type
+                (Canonical_Case_File_Name (Name_Id (Non_Canonical_Path)));
 
             --  To avoid processing the same directory several times, check
             --  if the directory is already in Recursive_Dirs. If it is, then
@@ -4999,9 +5004,11 @@ package body Prj.Nmsc is
                end if;
             end if;
 
-            Add_To_Or_Remove_From_List
+            Add_To_Or_Remove_From_Source_Dirs
               (Path_Id         => Canonical_Path,
-               Display_Path_Id => Non_Canonical_Path);
+               Display_Path_Id => Non_Canonical_Path,
+               Rank            => Rank,
+               Removed         => Removed);
 
             --  Now look for subdirectories. Do that even when this directory
             --  is already in the list, because some of its subdirectories may
@@ -5098,7 +5105,7 @@ package body Prj.Nmsc is
                Base_Dir : constant File_Name_Type := Name_Find;
                Root_Dir : constant String :=
                             Normalize_Pathname
-                              (Name      => Get_Name_String (Base_Dir),
+                              (Name      => Name_Buffer (1 .. Name_Len),
                                Directory =>
                                  Get_Name_String
                                    (Project.Directory.Display_Name),
@@ -5109,18 +5116,9 @@ package body Prj.Nmsc is
             begin
                if Root_Dir'Length = 0 then
                   Err_Vars.Error_Msg_File_1 := Base_Dir;
-
-                  if Location = No_Location then
-                     Error_Msg
-                       (Data.Flags,
-                        "{ is not a valid directory.",
-                        Project.Location, Project);
-                  else
-                     Error_Msg
-                       (Data.Flags,
-                        "{ is not a valid directory.",
-                        Location, Project);
-                  end if;
+                  Error_Msg
+                    (Data.Flags,
+                     "{ is not a valid directory.", Location, Project);
 
                else
                   --  We have an existing directory, we register it and all of
@@ -5158,57 +5156,18 @@ package body Prj.Nmsc is
 
                if not Dir_Exists then
                   Err_Vars.Error_Msg_File_1 := From;
-
-                  if Location = No_Location then
-                     Error_Msg
-                       (Data.Flags,
-                        "{ is not a valid directory",
-                        Project.Location, Project);
-                  else
-                     Error_Msg
-                       (Data.Flags,
-                        "{ is not a valid directory",
-                        Location, Project);
-                  end if;
+                  Error_Msg
+                    (Data.Flags,
+                     "{ is not a valid directory", Location, Project);
 
                else
-                  declare
-                     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;
-                     Display_Path      : constant String :=
-                                           Get_Name_String
-                                             (Path_Name.Display_Name);
-                     Last_Display_Path : constant Natural :=
-                                           Compute_Directory_Last
-                                             (Display_Path);
-                     Display_Path_Id   : Name_Id;
-
-                  begin
-                     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;
-
-                     Add_To_Or_Remove_From_List
-                       (Path_Id         => Path_Id,
-                        Display_Path_Id => Display_Path_Id);
-                  end;
+                  --  links have been resolved if necessary, and Path_Name
+                  --  always ends with a directory separator
+                  Add_To_Or_Remove_From_Source_Dirs
+                    (Path_Id         => Path_Name.Name,
+                     Display_Path_Id => Path_Name.Display_Name,
+                     Rank            => Rank,
+                     Removed         => Removed);
                end if;
             end;
          end if;
@@ -5378,7 +5337,7 @@ package body Prj.Nmsc is
 
       pragma Assert (Source_Dirs.Kind = List, "Source_Dirs is not a list");
 
-      if (not Source_Files.Default)
+      if not Source_Files.Default
         and then Source_Files.Values = Nil_String
       then
          Project.Source_Dirs := Nil_String;
@@ -5391,43 +5350,14 @@ package body Prj.Nmsc is
          end if;
 
       elsif Source_Dirs.Default then
-
          --  No Source_Dirs specified: the single source directory is the one
          --  containing the project file.
 
-         String_Element_Table.Append (Data.Tree.String_Elements,
-           (Value         => Name_Id (Project.Directory.Name),
-            Display_Value => Name_Id (Project.Directory.Display_Name),
-            Location      => No_Location,
-            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",
-               Get_Name_String (Project.Directory.Display_Name));
-         end if;
-
-      elsif Source_Dirs.Values = Nil_String then
-         if Project.Qualifier = Standard then
-            Error_Msg
-              (Data.Flags,
-               "a standard project cannot have no source directories",
-               Source_Dirs.Location, Project);
-         end if;
-
-         Project.Source_Dirs := Nil_String;
+         Add_To_Or_Remove_From_Source_Dirs
+           (Path_Id         => Project.Directory.Name,
+            Display_Path_Id => Project.Directory.Display_Name,
+            Rank            => 1,
+            Removed         => False);
 
       else
          declare
@@ -5446,6 +5376,15 @@ package body Prj.Nmsc is
                  (File_Name_Type (Element.Value), Element.Location, Rank);
                Source_Dir := Element.Next;
             end loop;
+
+            if Project.Source_Dirs = Nil_String
+              and then Project.Qualifier = Standard
+            then
+               Error_Msg
+                 (Data.Flags,
+                  "a standard project cannot have no source directories",
+                  Source_Dirs.Location, Project);
+            end if;
          end;
       end if;
 
@@ -6895,19 +6834,12 @@ package body Prj.Nmsc is
             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
+                  --  We use Element.Value, not Display_Value, because we want
+                  --  the symbolic links to be resolved when appropriate.
                   Source_Directory : constant String :=
-                                       Name_Buffer (1 .. Name_Len) &
-                                         Directory_Separator;
-
+                                       Get_Name_String (Element.Value)
+                                         & Directory_Separator;
                   Dir_Last : constant Natural :=
                                        Compute_Directory_Last
                                          (Source_Directory);
@@ -6915,6 +6847,7 @@ package body Prj.Nmsc is
                begin
                   if Current_Verbosity = High then
                      Write_Attr ("Source_Dir", Source_Directory);
+                     Write_Line (Num_Nod.Number'Img);
                   end if;
 
                   --  We look to every entry in the source directory
@@ -6964,7 +6897,6 @@ package body Prj.Nmsc is
                                             Resolve_Links   =>
                                               Opt.Follow_Links_For_Files,
                                             Case_Sensitive => True);
-                           --  Case_Sensitive set True (no folding)
 
                            Path : Path_Name_Type;
                            FF   : File_Found := Excluded_Sources_Htable.Get