aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/prj.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/prj.adb')
-rw-r--r--gcc/ada/prj.adb154
1 files changed, 91 insertions, 63 deletions
diff --git a/gcc/ada/prj.adb b/gcc/ada/prj.adb
index 06b2d38..32fa2a1 100644
--- a/gcc/ada/prj.adb
+++ b/gcc/ada/prj.adb
@@ -34,6 +34,7 @@ with Snames; use Snames;
with Uintp; use Uintp;
with Ada.Characters.Handling; use Ada.Characters.Handling;
+with Ada.Containers.Ordered_Sets;
with Ada.Unchecked_Deallocation;
with GNAT.Case_Util; use GNAT.Case_Util;
@@ -523,101 +524,128 @@ package body Prj is
Include_Aggregated : Boolean := True;
Imported_First : Boolean := False)
is
-
use Project_Boolean_Htable;
- Seen : Project_Boolean_Htable.Instance := Project_Boolean_Htable.Nil;
- procedure Recursive_Check
+ procedure Recursive_Check_Context
(Project : Project_Id;
Tree : Project_Tree_Ref;
In_Aggregate_Lib : Boolean);
- -- Check if a project has already been seen. If not seen, mark it
- -- as Seen, Call Action, and check all its imported and aggregated
- -- projects.
+ -- Recursively handle the project tree creating a new context for
+ -- keeping track about already handled projects.
- ---------------------
- -- Recursive_Check --
- ---------------------
+ -----------------------------
+ -- Recursive_Check_Context --
+ -----------------------------
- procedure Recursive_Check
+ procedure Recursive_Check_Context
(Project : Project_Id;
Tree : Project_Tree_Ref;
In_Aggregate_Lib : Boolean)
is
- List : Project_List;
- T : Project_Tree_Ref;
+ package Name_Id_Set is
+ new Ada.Containers.Ordered_Sets (Element_Type => Name_Id);
- begin
- if not Get (Seen, Project) then
+ Seen_Name : Name_Id_Set.Set;
+ -- This set is needed to ensure that we do not haandle the same
+ -- project twice in the context of aggregate libraries.
- -- Even if a project is aggregated multiple times, we will only
- -- return it once.
+ procedure Recursive_Check
+ (Project : Project_Id;
+ Tree : Project_Tree_Ref;
+ In_Aggregate_Lib : Boolean);
+ -- Check if project has already been seen. If not, mark it as Seen,
+ -- Call Action, and check all its imported and aggregated projects.
- Set (Seen, Project, True);
+ ---------------------
+ -- Recursive_Check --
+ ---------------------
- if not Imported_First then
- Action (Project, Tree, In_Aggregate_Lib, With_State);
- end if;
+ procedure Recursive_Check
+ (Project : Project_Id;
+ Tree : Project_Tree_Ref;
+ In_Aggregate_Lib : Boolean)
+ is
+ List : Project_List;
+ T : Project_Tree_Ref;
+
+ begin
+ if not Seen_Name.Contains (Project.Name) then
- -- Visit all extended projects
+ -- Even if a project is aggregated multiple times in an
+ -- aggregated library, we will only return it once.
- if Project.Extends /= No_Project then
- Recursive_Check (Project.Extends, Tree, In_Aggregate_Lib);
- end if;
+ Seen_Name.Include (Project.Name);
- -- Visit all imported projects if needed. This is not needed
- -- for an aggregate library as imported libraries are just
- -- there for dependency support.
+ if not Imported_First then
+ Action (Project, Tree, In_Aggregate_Lib, With_State);
+ end if;
+
+ -- Visit all extended projects
+
+ if Project.Extends /= No_Project then
+ Recursive_Check (Project.Extends, Tree, In_Aggregate_Lib);
+ end if;
+
+ -- Visit all imported projects
- if Project.Qualifier /= Aggregate_Library
- or else not Include_Aggregated
- then
List := Project.Imported_Projects;
while List /= null loop
Recursive_Check (List.Project, Tree, In_Aggregate_Lib);
List := List.Next;
end loop;
- end if;
- -- Visit all aggregated projects
+ -- Visit all aggregated projects
- if Include_Aggregated
- and then Project.Qualifier in Aggregate_Project
- then
- declare
- Agg : Aggregated_Project_List;
- begin
- Agg := Project.Aggregated_Projects;
- while Agg /= null loop
- pragma Assert (Agg.Project /= No_Project);
-
- -- For aggregated libraries, the tree must be the one
- -- of the aggregate library.
-
- if Project.Qualifier = Aggregate_Library then
- T := Tree;
- else
- T := Agg.Tree;
- end if;
-
- Recursive_Check
- (Agg.Project, T, Project.Qualifier = Aggregate_Library);
- Agg := Agg.Next;
- end loop;
- end;
- end if;
+ if Include_Aggregated
+ and then Project.Qualifier in Aggregate_Project
+ then
+ declare
+ Agg : Aggregated_Project_List;
+
+ begin
+ Agg := Project.Aggregated_Projects;
+ while Agg /= null loop
+ pragma Assert (Agg.Project /= No_Project);
+
+ -- For aggregated libraries, the tree must be the one
+ -- of the aggregate library.
+
+ if Project.Qualifier = Aggregate_Library then
+ T := Tree;
+ Recursive_Check (Agg.Project, T, True);
+
+ else
+ T := Agg.Tree;
+
+ -- Use a new context as we want to returns the same
+ -- project in different project tree for aggregated
+ -- projects.
- if Imported_First then
- Action (Project, Tree, In_Aggregate_Lib, With_State);
+ Recursive_Check_Context (Agg.Project, T, False);
+ end if;
+
+ Agg := Agg.Next;
+ end loop;
+ end;
+ end if;
+
+ if Imported_First then
+ Action (Project, Tree, In_Aggregate_Lib, With_State);
+ end if;
end if;
- end if;
- end Recursive_Check;
+ end Recursive_Check;
+
+ -- Start of processing for Recursive_Check_Context
+
+ begin
+ Recursive_Check (Project, Tree, In_Aggregate_Lib);
+ end Recursive_Check_Context;
-- Start of processing for For_Every_Project_Imported
begin
- Recursive_Check (Project => By, Tree => Tree, In_Aggregate_Lib => False);
- Reset (Seen);
+ Recursive_Check_Context
+ (Project => By, Tree => Tree, In_Aggregate_Lib => False);
end For_Every_Project_Imported;
-----------------