diff options
Diffstat (limited to 'gcc/ada/prj.adb')
-rw-r--r-- | gcc/ada/prj.adb | 154 |
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; ----------------- |