| ------------------------------------------------------------------------------ |
| -- -- |
| -- GNAT COMPILER COMPONENTS -- |
| -- -- |
| -- B I N D O . B U I L D E R S -- |
| -- -- |
| -- B o d y -- |
| -- -- |
| -- Copyright (C) 2019-2022, 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- -- |
| -- ware Foundation; either version 3, or (at your option) any later ver- -- |
| -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- |
| -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- |
| -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- |
| -- for more details. You should have received a copy of the GNU General -- |
| -- Public License distributed with GNAT; see file COPYING3. If not, go to -- |
| -- http://www.gnu.org/licenses for a complete copy of the license. -- |
| -- -- |
| -- GNAT was originally developed by the GNAT team at New York University. -- |
| -- Extensive contributions were provided by Ada Core Technologies Inc. -- |
| -- -- |
| ------------------------------------------------------------------------------ |
| |
| with Binderr; use Binderr; |
| with Butil; use Butil; |
| with Debug; use Debug; |
| with Opt; use Opt; |
| with Output; use Output; |
| with Types; use Types; |
| |
| with Bindo.Units; use Bindo.Units; |
| |
| with Bindo.Validators; |
| use Bindo.Validators; |
| use Bindo.Validators.Invocation_Graph_Validators; |
| use Bindo.Validators.Library_Graph_Validators; |
| |
| with Bindo.Writers; |
| use Bindo.Writers; |
| use Bindo.Writers.Phase_Writers; |
| |
| with GNAT; use GNAT; |
| with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables; |
| |
| package body Bindo.Builders is |
| |
| ------------------------------- |
| -- Invocation_Graph_Builders -- |
| ------------------------------- |
| |
| package body Invocation_Graph_Builders is |
| |
| ----------------- |
| -- Global data -- |
| ----------------- |
| |
| Inv_Graph : Invocation_Graph := Invocation_Graphs.Nil; |
| Lib_Graph : Library_Graph := Library_Graphs.Nil; |
| |
| ----------------------- |
| -- Local subprograms -- |
| ----------------------- |
| |
| procedure Create_Edge (IR_Id : Invocation_Relation_Id); |
| pragma Inline (Create_Edge); |
| -- Create a new edge for invocation relation IR_Id in invocation graph |
| -- Inv_Graph. |
| |
| procedure Create_Edges (U_Id : Unit_Id); |
| pragma Inline (Create_Edges); |
| -- Create new edges for all invocation relations of unit U_Id |
| |
| procedure Create_Vertex |
| (IC_Id : Invocation_Construct_Id; |
| Vertex : Library_Graph_Vertex_Id); |
| pragma Inline (Create_Vertex); |
| -- Create a new vertex for invocation construct IC_Id in invocation |
| -- graph Inv_Graph. The vertex is linked to vertex Vertex of library |
| -- graph Lib_Graph. |
| |
| procedure Create_Vertices (U_Id : Unit_Id); |
| pragma Inline (Create_Vertices); |
| -- Create new vertices for all invocation constructs of unit U_Id in |
| -- invocation graph Inv_Graph. |
| |
| function Declaration_Placement_Vertex |
| (Vertex : Library_Graph_Vertex_Id; |
| Placement : Declaration_Placement_Kind) |
| return Library_Graph_Vertex_Id; |
| pragma Inline (Declaration_Placement_Vertex); |
| -- Obtain the spec or body of vertex Vertex depending on the requested |
| -- placement in Placement. |
| |
| ---------------------------- |
| -- Build_Invocation_Graph -- |
| ---------------------------- |
| |
| function Build_Invocation_Graph |
| (Lib_G : Library_Graph) return Invocation_Graph |
| is |
| begin |
| pragma Assert (Present (Lib_G)); |
| |
| Start_Phase (Invocation_Graph_Construction); |
| |
| -- Prepare the global data |
| |
| Inv_Graph := |
| Create |
| (Initial_Vertices => Number_Of_Elaborable_Units, |
| Initial_Edges => Number_Of_Elaborable_Units, |
| Lib_Graph => Lib_G); |
| Lib_Graph := Lib_G; |
| |
| For_Each_Elaborable_Unit (Create_Vertices'Access); |
| For_Each_Elaborable_Unit (Create_Edges'Access); |
| |
| Validate_Invocation_Graph (Inv_Graph); |
| End_Phase (Invocation_Graph_Construction); |
| |
| return Inv_Graph; |
| end Build_Invocation_Graph; |
| |
| ----------------- |
| -- Create_Edge -- |
| ----------------- |
| |
| procedure Create_Edge (IR_Id : Invocation_Relation_Id) is |
| pragma Assert (Present (Inv_Graph)); |
| pragma Assert (Present (Lib_Graph)); |
| pragma Assert (Present (IR_Id)); |
| |
| Invoker_Sig : constant Invocation_Signature_Id := Invoker (IR_Id); |
| Target_Sig : constant Invocation_Signature_Id := Target (IR_Id); |
| |
| pragma Assert (Present (Invoker_Sig)); |
| pragma Assert (Present (Target_Sig)); |
| |
| begin |
| -- Nothing to do when the target denotes an invocation construct that |
| -- resides in a unit which will never be elaborated. |
| |
| if not Needs_Elaboration (Target_Sig) then |
| return; |
| end if; |
| |
| Add_Edge |
| (G => Inv_Graph, |
| Source => Corresponding_Vertex (Inv_Graph, Invoker_Sig), |
| Target => Corresponding_Vertex (Inv_Graph, Target_Sig), |
| IR_Id => IR_Id); |
| end Create_Edge; |
| |
| ------------------ |
| -- Create_Edges -- |
| ------------------ |
| |
| procedure Create_Edges (U_Id : Unit_Id) is |
| pragma Assert (Present (Inv_Graph)); |
| pragma Assert (Present (Lib_Graph)); |
| pragma Assert (Present (U_Id)); |
| |
| U_Rec : Unit_Record renames ALI.Units.Table (U_Id); |
| |
| begin |
| for IR_Id in U_Rec.First_Invocation_Relation .. |
| U_Rec.Last_Invocation_Relation |
| loop |
| Create_Edge (IR_Id); |
| end loop; |
| end Create_Edges; |
| |
| ------------------- |
| -- Create_Vertex -- |
| ------------------- |
| |
| procedure Create_Vertex |
| (IC_Id : Invocation_Construct_Id; |
| Vertex : Library_Graph_Vertex_Id) |
| is |
| begin |
| pragma Assert (Present (Inv_Graph)); |
| pragma Assert (Present (Lib_Graph)); |
| pragma Assert (Present (IC_Id)); |
| pragma Assert (Present (Vertex)); |
| |
| Add_Vertex |
| (G => Inv_Graph, |
| IC_Id => IC_Id, |
| Body_Vertex => |
| Declaration_Placement_Vertex |
| (Vertex => Vertex, |
| Placement => Body_Placement (IC_Id)), |
| Spec_Vertex => |
| Declaration_Placement_Vertex |
| (Vertex => Vertex, |
| Placement => Spec_Placement (IC_Id))); |
| end Create_Vertex; |
| |
| --------------------- |
| -- Create_Vertices -- |
| --------------------- |
| |
| procedure Create_Vertices (U_Id : Unit_Id) is |
| pragma Assert (Present (Inv_Graph)); |
| pragma Assert (Present (Lib_Graph)); |
| pragma Assert (Present (U_Id)); |
| |
| U_Rec : Unit_Record renames ALI.Units.Table (U_Id); |
| Vertex : constant Library_Graph_Vertex_Id := |
| Corresponding_Vertex (Lib_Graph, U_Id); |
| |
| begin |
| for IC_Id in U_Rec.First_Invocation_Construct .. |
| U_Rec.Last_Invocation_Construct |
| loop |
| Create_Vertex (IC_Id, Vertex); |
| end loop; |
| end Create_Vertices; |
| |
| ---------------------------------- |
| -- Declaration_Placement_Vertex -- |
| ---------------------------------- |
| |
| function Declaration_Placement_Vertex |
| (Vertex : Library_Graph_Vertex_Id; |
| Placement : Declaration_Placement_Kind) |
| return Library_Graph_Vertex_Id |
| is |
| begin |
| pragma Assert (Present (Lib_Graph)); |
| pragma Assert (Present (Vertex)); |
| |
| if Placement = In_Body then |
| return Proper_Body (Lib_Graph, Vertex); |
| else |
| pragma Assert (Placement = In_Spec); |
| return Proper_Spec (Lib_Graph, Vertex); |
| end if; |
| end Declaration_Placement_Vertex; |
| end Invocation_Graph_Builders; |
| |
| ---------------------------- |
| -- Library_Graph_Builders -- |
| ---------------------------- |
| |
| package body Library_Graph_Builders is |
| |
| --------------------- |
| -- Data structures -- |
| --------------------- |
| |
| procedure Destroy_Line_Number (Line : in out Logical_Line_Number); |
| pragma Inline (Destroy_Line_Number); |
| -- Destroy line number Line |
| |
| function Hash_Unit (U_Id : Unit_Id) return Bucket_Range_Type; |
| pragma Inline (Hash_Unit); |
| -- Obtain the hash value of key U_Id |
| |
| package Unit_Line_Tables is new Dynamic_Hash_Tables |
| (Key_Type => Unit_Id, |
| Value_Type => Logical_Line_Number, |
| No_Value => No_Line_Number, |
| Expansion_Threshold => 1.5, |
| Expansion_Factor => 2, |
| Compression_Threshold => 0.3, |
| Compression_Factor => 2, |
| "=" => "=", |
| Destroy_Value => Destroy_Line_Number, |
| Hash => Hash_Unit); |
| |
| ----------------- |
| -- Global data -- |
| ----------------- |
| |
| Lib_Graph : Library_Graph := Library_Graphs.Nil; |
| |
| Unit_To_Line : Unit_Line_Tables.Dynamic_Hash_Table := |
| Unit_Line_Tables.Nil; |
| -- The map of unit name -> line number, used to detect duplicate unit |
| -- names in the forced-elaboration-order file and report errors. |
| |
| ----------------------- |
| -- Local subprograms -- |
| ----------------------- |
| |
| procedure Add_Unit |
| (U_Id : Unit_Id; |
| Line : Logical_Line_Number); |
| pragma Inline (Add_Unit); |
| -- Create a relationship between unit U_Id and its declaration line in |
| -- map Unit_To_Line. |
| |
| procedure Create_Forced_Edge |
| (Pred : Unit_Id; |
| Succ : Unit_Id); |
| pragma Inline (Create_Forced_Edge); |
| -- Create a new forced edge between predecessor unit Pred and successor |
| -- unit Succ. |
| |
| procedure Create_Forced_Edges; |
| pragma Inline (Create_Forced_Edges); |
| -- Inspect the contents of the forced-elaboration-order file, and create |
| -- specialized edges for each valid pair of units listed within. |
| |
| procedure Create_Spec_And_Body_Edge (U_Id : Unit_Id); |
| pragma Inline (Create_Spec_And_Body_Edge); |
| -- Establish a link between the spec and body of unit U_Id. In certain |
| -- cases this may result in a new edge which is added to library graph |
| -- Lib_Graph. |
| |
| procedure Create_Vertex (U_Id : Unit_Id); |
| pragma Inline (Create_Vertex); |
| -- Create a new vertex for unit U_Id in library graph Lib_Graph |
| |
| procedure Create_With_Edge |
| (W_Id : With_Id; |
| Succ : Library_Graph_Vertex_Id); |
| pragma Inline (Create_With_Edge); |
| -- Create a new edge for with W_Id where the predecessor is the library |
| -- graph vertex of the withed unit, and the successor is Succ. The edge |
| -- is added to library graph Lib_Graph. |
| |
| procedure Create_With_Edges (U_Id : Unit_Id); |
| pragma Inline (Create_With_Edges); |
| -- Establish links between unit U_Id and its predecessor units. The new |
| -- edges are added to library graph Lib_Graph. |
| |
| procedure Create_With_Edges |
| (U_Id : Unit_Id; |
| Succ : Library_Graph_Vertex_Id); |
| pragma Inline (Create_With_Edges); |
| -- Create new edges for all withs of unit U_Id where the predecessor is |
| -- some withed unit, and the successor is Succ. The edges are added to |
| -- library graph Lib_Graph. |
| |
| procedure Duplicate_Unit_Error |
| (U_Id : Unit_Id; |
| Nam : Unit_Name_Type; |
| Line : Logical_Line_Number); |
| pragma Inline (Duplicate_Unit_Error); |
| -- Emit an error concerning the duplication of unit U_Id with name Nam |
| -- that is redeclared in the forced-elaboration-order file at line Line. |
| |
| procedure Internal_Unit_Info (Nam : Unit_Name_Type); |
| pragma Inline (Internal_Unit_Info); |
| -- Emit an information message concerning the omission of an internal |
| -- unit with name Nam from the creation of forced edges. |
| |
| function Is_Duplicate_Unit (U_Id : Unit_Id) return Boolean; |
| pragma Inline (Is_Duplicate_Unit); |
| -- Determine whether unit U_Id is already recorded in map Unit_To_Line |
| |
| function Is_Significant_With (W_Id : With_Id) return Boolean; |
| pragma Inline (Is_Significant_With); |
| -- Determine whether with W_Id plays a significant role in elaboration |
| |
| procedure Missing_Unit_Info (Nam : Unit_Name_Type); |
| pragma Inline (Missing_Unit_Info); |
| -- Emit an information message concerning the omission of an undefined |
| -- unit found in the forced-elaboration-order file. |
| |
| -------------- |
| -- Add_Unit -- |
| -------------- |
| |
| procedure Add_Unit |
| (U_Id : Unit_Id; |
| Line : Logical_Line_Number) |
| is |
| begin |
| pragma Assert (Present (U_Id)); |
| |
| Unit_Line_Tables.Put (Unit_To_Line, U_Id, Line); |
| end Add_Unit; |
| |
| ------------------------- |
| -- Build_Library_Graph -- |
| ------------------------- |
| |
| function Build_Library_Graph return Library_Graph is |
| begin |
| Start_Phase (Library_Graph_Construction); |
| |
| -- Prepare the global data |
| |
| Lib_Graph := |
| Create |
| (Initial_Vertices => Number_Of_Elaborable_Units, |
| Initial_Edges => Number_Of_Elaborable_Units); |
| |
| For_Each_Elaborable_Unit (Create_Vertex'Access); |
| For_Each_Elaborable_Unit (Create_Spec_And_Body_Edge'Access); |
| For_Each_Elaborable_Unit (Create_With_Edges'Access); |
| Create_Forced_Edges; |
| |
| Validate_Library_Graph (Lib_Graph); |
| End_Phase (Library_Graph_Construction); |
| |
| return Lib_Graph; |
| end Build_Library_Graph; |
| |
| ------------------------ |
| -- Create_Forced_Edge -- |
| ------------------------ |
| |
| procedure Create_Forced_Edge |
| (Pred : Unit_Id; |
| Succ : Unit_Id) |
| is |
| pragma Assert (Present (Pred)); |
| pragma Assert (Present (Succ)); |
| |
| Pred_Vertex : constant Library_Graph_Vertex_Id := |
| Corresponding_Vertex (Lib_Graph, Pred); |
| Succ_Vertex : constant Library_Graph_Vertex_Id := |
| Corresponding_Vertex (Lib_Graph, Succ); |
| |
| begin |
| Write_Unit_Name (Name (Pred)); |
| Write_Str (" <-- "); |
| Write_Unit_Name (Name (Succ)); |
| Write_Eol; |
| |
| Add_Edge |
| (G => Lib_Graph, |
| Pred => Pred_Vertex, |
| Succ => Succ_Vertex, |
| Kind => Forced_Edge, |
| Activates_Task => False); |
| end Create_Forced_Edge; |
| |
| ------------------------- |
| -- Create_Forced_Edges -- |
| ------------------------- |
| |
| procedure Create_Forced_Edges is |
| Current_Unit : Unit_Id; |
| Iter : Forced_Units_Iterator; |
| Previous_Unit : Unit_Id; |
| Unit_Line : Logical_Line_Number; |
| Unit_Name : Unit_Name_Type; |
| |
| begin |
| Previous_Unit := No_Unit_Id; |
| Unit_To_Line := Unit_Line_Tables.Create (20); |
| |
| -- Inspect the contents of the forced-elaboration-order file supplied |
| -- to the binder using switch -f, and diagnose each unit accordingly. |
| |
| Iter := Iterate_Forced_Units; |
| while Has_Next (Iter) loop |
| Next (Iter, Unit_Name, Unit_Line); |
| |
| Current_Unit := Corresponding_Unit (Unit_Name); |
| |
| if not Present (Current_Unit) then |
| Missing_Unit_Info (Unit_Name); |
| |
| elsif Is_Internal_Unit (Current_Unit) then |
| Internal_Unit_Info (Unit_Name); |
| |
| elsif Is_Duplicate_Unit (Current_Unit) then |
| Duplicate_Unit_Error (Current_Unit, Unit_Name, Unit_Line); |
| |
| -- Otherwise the unit is a valid candidate for a vertex. Create a |
| -- forced edge between each pair of units. |
| |
| else |
| Add_Unit (Current_Unit, Unit_Line); |
| |
| if Present (Previous_Unit) then |
| Create_Forced_Edge |
| (Pred => Previous_Unit, |
| Succ => Current_Unit); |
| end if; |
| |
| Previous_Unit := Current_Unit; |
| end if; |
| end loop; |
| |
| Unit_Line_Tables.Destroy (Unit_To_Line); |
| end Create_Forced_Edges; |
| |
| ------------------------------- |
| -- Create_Spec_And_Body_Edge -- |
| ------------------------------- |
| |
| procedure Create_Spec_And_Body_Edge (U_Id : Unit_Id) is |
| Extra_Vertex : Library_Graph_Vertex_Id; |
| Vertex : Library_Graph_Vertex_Id; |
| |
| begin |
| pragma Assert (Present (Lib_Graph)); |
| pragma Assert (Present (U_Id)); |
| |
| Vertex := Corresponding_Vertex (Lib_Graph, U_Id); |
| |
| -- The unit denotes a body that completes a previous spec. Link the |
| -- spec and body. Add an edge between the predecessor spec and the |
| -- successor body. |
| |
| if Is_Body_With_Spec (Lib_Graph, Vertex) then |
| Extra_Vertex := |
| Corresponding_Vertex (Lib_Graph, Corresponding_Spec (U_Id)); |
| Set_Corresponding_Item (Lib_Graph, Vertex, Extra_Vertex); |
| |
| Add_Edge |
| (G => Lib_Graph, |
| Pred => Extra_Vertex, |
| Succ => Vertex, |
| Kind => Spec_Before_Body_Edge, |
| Activates_Task => False); |
| |
| -- The unit denotes a spec with a completing body. Link the spec and |
| -- body. |
| |
| elsif Is_Spec_With_Body (Lib_Graph, Vertex) then |
| Extra_Vertex := |
| Corresponding_Vertex (Lib_Graph, Corresponding_Body (U_Id)); |
| Set_Corresponding_Item (Lib_Graph, Vertex, Extra_Vertex); |
| end if; |
| end Create_Spec_And_Body_Edge; |
| |
| ------------------- |
| -- Create_Vertex -- |
| ------------------- |
| |
| procedure Create_Vertex (U_Id : Unit_Id) is |
| begin |
| pragma Assert (Present (Lib_Graph)); |
| pragma Assert (Present (U_Id)); |
| |
| Add_Vertex |
| (G => Lib_Graph, |
| U_Id => U_Id); |
| end Create_Vertex; |
| |
| ---------------------- |
| -- Create_With_Edge -- |
| ---------------------- |
| |
| procedure Create_With_Edge |
| (W_Id : With_Id; |
| Succ : Library_Graph_Vertex_Id) |
| is |
| pragma Assert (Present (Lib_Graph)); |
| pragma Assert (Present (W_Id)); |
| pragma Assert (Present (Succ)); |
| |
| Withed_Rec : With_Record renames Withs.Table (W_Id); |
| Withed_U_Id : constant Unit_Id := |
| Corresponding_Unit (Withed_Rec.Uname); |
| |
| Kind : Library_Graph_Edge_Kind; |
| Withed_Vertex : Library_Graph_Vertex_Id; |
| |
| begin |
| -- Nothing to do when the withed unit does not need to be elaborated. |
| -- This prevents spurious dependencies that can never be satisfied. |
| |
| if not Needs_Elaboration (Withed_U_Id) then |
| return; |
| end if; |
| |
| Withed_Vertex := Corresponding_Vertex (Lib_Graph, Withed_U_Id); |
| |
| -- The with comes with pragma Elaborate. Treat the edge as a with |
| -- edge when switch -d_e (ignore the effects of pragma Elaborate) |
| -- is in effect. |
| |
| if Withed_Rec.Elaborate |
| and then not Debug_Flag_Underscore_E |
| then |
| Kind := Elaborate_Edge; |
| |
| -- The withed unit is a spec with a completing body. Add an edge |
| -- between the body of the withed predecessor and the withing |
| -- successor. |
| |
| if Is_Spec_With_Body (Lib_Graph, Withed_Vertex) then |
| Add_Edge |
| (G => Lib_Graph, |
| Pred => |
| Corresponding_Vertex |
| (Lib_Graph, Corresponding_Body (Withed_U_Id)), |
| Succ => Succ, |
| Kind => Kind, |
| Activates_Task => False); |
| end if; |
| |
| -- The with comes with pragma Elaborate_All. Treat the edge as a with |
| -- edge when switch -d_a (ignore the effects of pragma Elaborate_All) |
| -- is in effect. |
| |
| elsif Withed_Rec.Elaborate_All |
| and then not Debug_Flag_Underscore_A |
| then |
| Kind := Elaborate_All_Edge; |
| |
| -- Otherwise this is a regular with |
| |
| else |
| Kind := With_Edge; |
| end if; |
| |
| -- Add an edge between the withed predecessor unit and the withing |
| -- successor. |
| |
| Add_Edge |
| (G => Lib_Graph, |
| Pred => Withed_Vertex, |
| Succ => Succ, |
| Kind => Kind, |
| Activates_Task => False); |
| end Create_With_Edge; |
| |
| ----------------------- |
| -- Create_With_Edges -- |
| ----------------------- |
| |
| procedure Create_With_Edges (U_Id : Unit_Id) is |
| begin |
| pragma Assert (Present (Lib_Graph)); |
| pragma Assert (Present (U_Id)); |
| |
| Create_With_Edges |
| (U_Id => U_Id, |
| Succ => Corresponding_Vertex (Lib_Graph, U_Id)); |
| end Create_With_Edges; |
| |
| ----------------------- |
| -- Create_With_Edges -- |
| ----------------------- |
| |
| procedure Create_With_Edges |
| (U_Id : Unit_Id; |
| Succ : Library_Graph_Vertex_Id) |
| is |
| pragma Assert (Present (Lib_Graph)); |
| pragma Assert (Present (U_Id)); |
| pragma Assert (Present (Succ)); |
| |
| U_Rec : Unit_Record renames ALI.Units.Table (U_Id); |
| |
| begin |
| for W_Id in U_Rec.First_With .. U_Rec.Last_With loop |
| if Is_Significant_With (W_Id) then |
| Create_With_Edge (W_Id, Succ); |
| end if; |
| end loop; |
| end Create_With_Edges; |
| |
| ------------------ |
| -- Destroy_Unit -- |
| ------------------ |
| |
| procedure Destroy_Line_Number (Line : in out Logical_Line_Number) is |
| pragma Unreferenced (Line); |
| begin |
| null; |
| end Destroy_Line_Number; |
| |
| -------------------------- |
| -- Duplicate_Unit_Error -- |
| -------------------------- |
| |
| procedure Duplicate_Unit_Error |
| (U_Id : Unit_Id; |
| Nam : Unit_Name_Type; |
| Line : Logical_Line_Number) |
| is |
| pragma Assert (Present (U_Id)); |
| pragma Assert (Present (Nam)); |
| |
| Prev_Line : constant Logical_Line_Number := |
| Unit_Line_Tables.Get (Unit_To_Line, U_Id); |
| |
| begin |
| Error_Msg_Nat_1 := Nat (Line); |
| Error_Msg_Nat_2 := Nat (Prev_Line); |
| Error_Msg_Unit_1 := Nam; |
| |
| Error_Msg |
| (Force_Elab_Order_File.all |
| & ":#: duplicate unit name $ from line #"); |
| end Duplicate_Unit_Error; |
| |
| --------------- |
| -- Hash_Unit -- |
| --------------- |
| |
| function Hash_Unit (U_Id : Unit_Id) return Bucket_Range_Type is |
| begin |
| pragma Assert (Present (U_Id)); |
| |
| return Bucket_Range_Type (U_Id); |
| end Hash_Unit; |
| |
| ------------------------ |
| -- Internal_Unit_Info -- |
| ------------------------ |
| |
| procedure Internal_Unit_Info (Nam : Unit_Name_Type) is |
| begin |
| pragma Assert (Present (Nam)); |
| |
| Write_Line |
| ("""" & Get_Name_String (Nam) & """: predefined unit ignored"); |
| end Internal_Unit_Info; |
| |
| ----------------------- |
| -- Is_Duplicate_Unit -- |
| ----------------------- |
| |
| function Is_Duplicate_Unit (U_Id : Unit_Id) return Boolean is |
| begin |
| pragma Assert (Present (U_Id)); |
| |
| return Unit_Line_Tables.Contains (Unit_To_Line, U_Id); |
| end Is_Duplicate_Unit; |
| |
| ------------------------- |
| -- Is_Significant_With -- |
| ------------------------- |
| |
| function Is_Significant_With (W_Id : With_Id) return Boolean is |
| pragma Assert (Present (W_Id)); |
| |
| Withed_Rec : With_Record renames Withs.Table (W_Id); |
| Withed_U_Id : constant Unit_Id := |
| Corresponding_Unit (Withed_Rec.Uname); |
| |
| begin |
| -- Nothing to do for a unit which does not exist any more |
| |
| if not Present (Withed_U_Id) then |
| return False; |
| |
| -- Nothing to do for a limited with |
| |
| elsif Withed_Rec.Limited_With then |
| return False; |
| |
| -- Nothing to do when the unit does not need to be elaborated |
| |
| elsif not Needs_Elaboration (Withed_U_Id) then |
| return False; |
| end if; |
| |
| return True; |
| end Is_Significant_With; |
| |
| ----------------------- |
| -- Missing_Unit_Info -- |
| ----------------------- |
| |
| procedure Missing_Unit_Info (Nam : Unit_Name_Type) is |
| begin |
| pragma Assert (Present (Nam)); |
| |
| Write_Line |
| ("""" & Get_Name_String (Nam) & """: not present; ignored"); |
| end Missing_Unit_Info; |
| end Library_Graph_Builders; |
| |
| end Bindo.Builders; |