Commit 2f1b20a9 by Ed Schonberg Committed by Arnaud Charlet

exp_ch6.adb (Expand_Call): If an actual is a function call rewritten from object notation...

2005-09-01  Ed Schonberg  <schonberg@adacore.com>
	    Hristian Kirtchev  <kirtchev@adacore.com>
	    Javier Miranda  <miranda@adacore.com>

	* exp_ch6.adb (Expand_Call): If an actual is a function call rewritten
	from object notation, the original node is unanalyzed and carries no
	semantic information, so that accessiblity checks must be performed on
	the type of the actual itself.
	(Expand_N_Subprogram_Declaration): Change last actual parameter for
	compatibility with Build_Protected_Sub_Specification.
	(Check_Overriding_Inherited_Interfaces): Add suport to handle
	overloaded primitives.
	(Register_Interface_DT_Entry): Use the new name of the formal
	the the calls to Expand_Interface_Thunk

	* exp_dbug.ads: Augment comments on encoding of protected types to
	include the generation of dispatching subprograms when the type
	implements at least one interface.

	* lib.ads: Extend information in Load_Stack to include whether a given
	load comes from a Limited_With_Clause.

	* lib-load.adb (From_Limited_With_Chain): New predicate to determine
	whether a potential circularity is harmless, because it includes units
	loaded through a limited_with clause. Extends previous treatment which
	did not handle properly arbitrary combinations of limited and
	non-limited clauses.

From-SVN: r103861
parent 0f716470
...@@ -34,7 +34,6 @@ with Exp_Ch2; use Exp_Ch2; ...@@ -34,7 +34,6 @@ with Exp_Ch2; use Exp_Ch2;
with Exp_Ch3; use Exp_Ch3; with Exp_Ch3; use Exp_Ch3;
with Exp_Ch7; use Exp_Ch7; with Exp_Ch7; use Exp_Ch7;
with Exp_Ch9; use Exp_Ch9; with Exp_Ch9; use Exp_Ch9;
with Exp_Ch11; use Exp_Ch11;
with Exp_Dbug; use Exp_Dbug; with Exp_Dbug; use Exp_Dbug;
with Exp_Disp; use Exp_Disp; with Exp_Disp; use Exp_Disp;
with Exp_Dist; use Exp_Dist; with Exp_Dist; use Exp_Dist;
...@@ -172,10 +171,10 @@ package body Exp_Ch6 is ...@@ -172,10 +171,10 @@ package body Exp_Ch6 is
and then In_Open_Scopes (Scope (Etype (Typ))) and then In_Open_Scopes (Scope (Etype (Typ)))
and then Typ = Base_Type (Typ) and then Typ = Base_Type (Typ)
then then
-- Subp overrides an inherited private operation if there is -- Subp overrides an inherited private operation if there is an
-- an inherited operation with a different name than Subp (see -- inherited operation with a different name than Subp (see
-- Derive_Subprogram) whose Alias is a hidden subprogram with -- Derive_Subprogram) whose Alias is a hidden subprogram with the
-- the same name as Subp. -- same name as Subp.
Op_Elmt := First_Elmt (Op_List); Op_Elmt := First_Elmt (Op_List);
while Present (Op_Elmt) loop while Present (Op_Elmt) loop
...@@ -211,12 +210,12 @@ package body Exp_Ch6 is ...@@ -211,12 +210,12 @@ package body Exp_Ch6 is
-- List of recursive calls in body of procedure -- List of recursive calls in body of procedure
Shad_List : constant Elist_Id := New_Elmt_List; Shad_List : constant Elist_Id := New_Elmt_List;
-- List of entity id's for entities created to capture the -- List of entity id's for entities created to capture the value of
-- value of referenced globals on entry to the procedure. -- referenced globals on entry to the procedure.
Scop : constant Uint := Scope_Depth (Spec); Scop : constant Uint := Scope_Depth (Spec);
-- This is used to record the scope depth of the current -- This is used to record the scope depth of the current procedure, so
-- procedure, so that we can identify global references. -- that we can identify global references.
Max_Vars : constant := 4; Max_Vars : constant := 4;
-- Do not test more than four global variables -- Do not test more than four global variables
...@@ -359,9 +358,9 @@ package body Exp_Ch6 is ...@@ -359,9 +358,9 @@ package body Exp_Ch6 is
-- Start of processing for Detect_Infinite_Recursion -- Start of processing for Detect_Infinite_Recursion
begin begin
-- Do not attempt detection in No_Implicit_Conditional mode, -- Do not attempt detection in No_Implicit_Conditional mode, since we
-- since we won't be able to generate the code to handle the -- won't be able to generate the code to handle the recursion in any
-- recursion in any case. -- case.
if Restriction_Active (No_Implicit_Conditionals) then if Restriction_Active (No_Implicit_Conditionals) then
return; return;
...@@ -372,9 +371,9 @@ package body Exp_Ch6 is ...@@ -372,9 +371,9 @@ package body Exp_Ch6 is
if Traverse_Body (N) = Abandon then if Traverse_Body (N) = Abandon then
return; return;
-- We must have a call, since Has_Recursive_Call was set. If not -- We must have a call, since Has_Recursive_Call was set. If not just
-- just ignore (this is only an error check, so if we have a funny -- ignore (this is only an error check, so if we have a funny situation,
-- situation, due to bugs or errors, we do not want to bomb!) -- due to bugs or errors, we do not want to bomb!)
elsif Is_Empty_Elmt_List (Call_List) then elsif Is_Empty_Elmt_List (Call_List) then
return; return;
...@@ -382,15 +381,15 @@ package body Exp_Ch6 is ...@@ -382,15 +381,15 @@ package body Exp_Ch6 is
-- Here is the case where we detect recursion at compile time -- Here is the case where we detect recursion at compile time
-- Push our current scope for analyzing the declarations and -- Push our current scope for analyzing the declarations and code that
-- code that we will insert for the checking. -- we will insert for the checking.
New_Scope (Spec); New_Scope (Spec);
-- This loop builds temporary variables for each of the -- This loop builds temporary variables for each of the referenced
-- referenced globals, so that at the end of the loop the -- globals, so that at the end of the loop the list Shad_List contains
-- list Shad_List contains these temporaries in one-to-one -- these temporaries in one-to-one correspondence with the elements in
-- correspondence with the elements in Var_List. -- Var_List.
Last := Empty; Last := Empty;
Elm := First_Elmt (Var_List); Elm := First_Elmt (Var_List);
...@@ -401,10 +400,10 @@ package body Exp_Ch6 is ...@@ -401,10 +400,10 @@ package body Exp_Ch6 is
Chars => New_Internal_Name ('S')); Chars => New_Internal_Name ('S'));
Append_Elmt (Ent, Shad_List); Append_Elmt (Ent, Shad_List);
-- Insert a declaration for this temporary at the start of -- Insert a declaration for this temporary at the start of the
-- the declarations for the procedure. The temporaries are -- declarations for the procedure. The temporaries are declared as
-- declared as constant objects initialized to the current -- constant objects initialized to the current values of the
-- values of the corresponding temporaries. -- corresponding temporaries.
Decl := Decl :=
Make_Object_Declaration (Loc, Make_Object_Declaration (Loc,
...@@ -940,7 +939,6 @@ package body Exp_Ch6 is ...@@ -940,7 +939,6 @@ package body Exp_Ch6 is
procedure Reset_Packed_Prefix is procedure Reset_Packed_Prefix is
Pfx : Node_Id := Actual; Pfx : Node_Id := Actual;
begin begin
loop loop
Set_Analyzed (Pfx, False); Set_Analyzed (Pfx, False);
...@@ -953,11 +951,10 @@ package body Exp_Ch6 is ...@@ -953,11 +951,10 @@ package body Exp_Ch6 is
-- Start of processing for Expand_Actuals -- Start of processing for Expand_Actuals
begin begin
Formal := First_Formal (Subp);
Actual := First_Actual (N);
Post_Call := New_List; Post_Call := New_List;
Formal := First_Formal (Subp);
Actual := First_Actual (N);
while Present (Formal) loop while Present (Formal) loop
E_Formal := Etype (Formal); E_Formal := Etype (Formal);
...@@ -1155,10 +1152,9 @@ package body Exp_Ch6 is ...@@ -1155,10 +1152,9 @@ package body Exp_Ch6 is
if not Is_Empty_List (Post_Call) then if not Is_Empty_List (Post_Call) then
-- If call is not a list member, it must be the triggering -- If call is not a list member, it must be the triggering statement
-- statement of a triggering alternative or an entry call -- of a triggering alternative or an entry call alternative, and we
-- alternative, and we can add the post call stuff to the -- can add the post call stuff to the corresponding statement list.
-- corresponding statement list.
if not Is_List_Member (N) then if not Is_List_Member (N) then
declare declare
...@@ -1219,22 +1215,27 @@ package body Exp_Ch6 is ...@@ -1219,22 +1215,27 @@ package body Exp_Ch6 is
Actual : Node_Id; Actual : Node_Id;
Formal : Entity_Id; Formal : Entity_Id;
Prev : Node_Id := Empty; Prev : Node_Id := Empty;
Prev_Orig : Node_Id;
Prev_Orig : Node_Id;
-- Original node for an actual, which may have been rewritten. If the
-- actual is a function call that has been transformed from a selected
-- component, the original node is unanalyzed. Otherwise, it carries
-- semantic information used to generate additional actuals.
Scop : Entity_Id; Scop : Entity_Id;
Extra_Actuals : List_Id := No_List; Extra_Actuals : List_Id := No_List;
Cond : Node_Id;
CW_Interface_Formals_Present : Boolean := False; CW_Interface_Formals_Present : Boolean := False;
procedure Add_Actual_Parameter (Insert_Param : Node_Id); procedure Add_Actual_Parameter (Insert_Param : Node_Id);
-- Adds one entry to the end of the actual parameter list. Used for -- Adds one entry to the end of the actual parameter list. Used for
-- default parameters and for extra actuals (for Extra_Formals). -- default parameters and for extra actuals (for Extra_Formals). The
-- The argument is an N_Parameter_Association node. -- argument is an N_Parameter_Association node.
procedure Add_Extra_Actual (Expr : Node_Id; EF : Entity_Id); procedure Add_Extra_Actual (Expr : Node_Id; EF : Entity_Id);
-- Adds an extra actual to the list of extra actuals. Expr -- Adds an extra actual to the list of extra actuals. Expr is the
-- is the expression for the value of the actual, EF is the -- expression for the value of the actual, EF is the entity for the
-- entity for the extra formal. -- extra formal.
function Inherited_From_Formal (S : Entity_Id) return Entity_Id; function Inherited_From_Formal (S : Entity_Id) return Entity_Id;
-- Within an instance, a type derived from a non-tagged formal derived -- Within an instance, a type derived from a non-tagged formal derived
...@@ -1324,8 +1325,8 @@ package body Exp_Ch6 is ...@@ -1324,8 +1325,8 @@ package body Exp_Ch6 is
if Nkind (Parent (S)) /= N_Full_Type_Declaration if Nkind (Parent (S)) /= N_Full_Type_Declaration
or else not Is_Derived_Type (Defining_Identifier (Parent (S))) or else not Is_Derived_Type (Defining_Identifier (Parent (S)))
or else Nkind (Type_Definition (Original_Node (Parent (S)))) or else Nkind (Type_Definition (Original_Node (Parent (S)))) /=
/= N_Derived_Type_Definition N_Derived_Type_Definition
or else not In_Instance or else not In_Instance
then then
return Empty; return Empty;
...@@ -1353,31 +1354,29 @@ package body Exp_Ch6 is ...@@ -1353,31 +1354,29 @@ package body Exp_Ch6 is
Gen_Par := Generic_Parent_Type (Parent (Par)); Gen_Par := Generic_Parent_Type (Parent (Par));
end if; end if;
-- If the generic parent type is still the generic type, this -- If the generic parent type is still the generic type, this is a
-- is a private formal, not a derived formal, and there are no -- private formal, not a derived formal, and there are no operations
-- operations inherited from the formal. -- inherited from the formal.
if Nkind (Parent (Gen_Par)) = N_Formal_Type_Declaration then if Nkind (Parent (Gen_Par)) = N_Formal_Type_Declaration then
return Empty; return Empty;
end if; end if;
Gen_Prim := Collect_Primitive_Operations (Gen_Par); Gen_Prim := Collect_Primitive_Operations (Gen_Par);
Elmt := First_Elmt (Gen_Prim);
Elmt := First_Elmt (Gen_Prim);
while Present (Elmt) loop while Present (Elmt) loop
if Chars (Node (Elmt)) = Chars (S) then if Chars (Node (Elmt)) = Chars (S) then
declare declare
F1 : Entity_Id; F1 : Entity_Id;
F2 : Entity_Id; F2 : Entity_Id;
begin
begin
F1 := First_Formal (S); F1 := First_Formal (S);
F2 := First_Formal (Node (Elmt)); F2 := First_Formal (Node (Elmt));
while Present (F1) while Present (F1)
and then Present (F2) and then Present (F2)
loop loop
if Etype (F1) = Etype (F2) if Etype (F1) = Etype (F2)
or else Etype (F2) = Gen_Par or else Etype (F2) = Gen_Par
then then
...@@ -1448,7 +1447,8 @@ package body Exp_Ch6 is ...@@ -1448,7 +1447,8 @@ package body Exp_Ch6 is
begin begin
-- The case we catch is where the first argument is obtained -- The case we catch is where the first argument is obtained
-- using the Identity attribute (which must always be non-null) -- using the Identity attribute (which must always be
-- non-null).
if Nkind (FA) = N_Attribute_Reference if Nkind (FA) = N_Attribute_Reference
and then Attribute_Name (FA) = Name_Identity and then Attribute_Name (FA) = Name_Identity
...@@ -1490,8 +1490,14 @@ package body Exp_Ch6 is ...@@ -1490,8 +1490,14 @@ package body Exp_Ch6 is
Prev := Actual; Prev := Actual;
Prev_Orig := Original_Node (Prev); Prev_Orig := Original_Node (Prev);
if not Analyzed (Prev_Orig)
and then Nkind (Actual) = N_Function_Call
then
Prev_Orig := Prev;
end if;
-- Ada 2005 (AI-251): Check if any formal is a class-wide interface -- Ada 2005 (AI-251): Check if any formal is a class-wide interface
-- to expand it in a further round -- to expand it in a further round.
CW_Interface_Formals_Present := CW_Interface_Formals_Present :=
CW_Interface_Formals_Present CW_Interface_Formals_Present
...@@ -1539,13 +1545,13 @@ package body Exp_Ch6 is ...@@ -1539,13 +1545,13 @@ package body Exp_Ch6 is
-- test applies to the actual, not the target type. -- test applies to the actual, not the target type.
declare declare
Act_Prev : Node_Id := Prev; Act_Prev : Node_Id;
begin begin
-- Test for unchecked conversions as well, which can -- Test for unchecked conversions as well, which can occur
-- occur as out parameter actuals on calls to stream -- as out parameter actuals on calls to stream procedures.
-- procedures.
Act_Prev := Prev;
while Nkind (Act_Prev) = N_Type_Conversion while Nkind (Act_Prev) = N_Type_Conversion
or else Nkind (Act_Prev) = N_Unchecked_Type_Conversion or else Nkind (Act_Prev) = N_Unchecked_Type_Conversion
loop loop
...@@ -1669,55 +1675,59 @@ package body Exp_Ch6 is ...@@ -1669,55 +1675,59 @@ package body Exp_Ch6 is
end if; end if;
end if; end if;
-- Perform the check of 4.6(49) that prevents a null value -- Perform the check of 4.6(49) that prevents a null value from being
-- from being passed as an actual to an access parameter. -- passed as an actual to an access parameter. Note that the check is
-- Note that the check is elided in the common cases of -- elided in the common cases of passing an access attribute or
-- passing an access attribute or access parameter as an -- access parameter as an actual. Also, we currently don't enforce
-- actual. Also, we currently don't enforce this check for -- this check for expander-generated actuals and when -gnatdj is set.
-- expander-generated actuals and when -gnatdj is set.
if Ekind (Etype (Formal)) /= E_Anonymous_Access_Type if Ada_Version >= Ada_05 then
or else Access_Checks_Suppressed (Subp)
then
null;
elsif Debug_Flag_J then -- Ada 2005 (AI-231): Check null-excluding access types
null;
elsif not Comes_From_Source (Prev) then if Is_Access_Type (Etype (Formal))
null; and then Can_Never_Be_Null (Etype (Formal))
and then Nkind (Prev) /= N_Raise_Constraint_Error
and then (Nkind (Prev) = N_Null
or else not Can_Never_Be_Null (Etype (Prev)))
then
Install_Null_Excluding_Check (Prev);
end if;
elsif Is_Entity_Name (Prev) -- Ada_Version < Ada_05
and then Ekind (Etype (Prev)) = E_Anonymous_Access_Type
then
null;
elsif Nkind (Prev) = N_Allocator else
or else Nkind (Prev) = N_Attribute_Reference if Ekind (Etype (Formal)) /= E_Anonymous_Access_Type
then or else Access_Checks_Suppressed (Subp)
null; then
null;
-- Suppress null checks when passing to access parameters elsif Debug_Flag_J then
-- of Java subprograms. (Should this be done for other null;
-- foreign conventions as well ???)
elsif Convention (Subp) = Convention_Java then elsif not Comes_From_Source (Prev) then
null; null;
-- Ada 2005 (AI-231): do not force the check in case of Ada 2005 elsif Is_Entity_Name (Prev)
-- unless it is a null-excluding type and then Ekind (Etype (Prev)) = E_Anonymous_Access_Type
then
null;
elsif Ada_Version < Ada_05 elsif Nkind (Prev) = N_Allocator
or else Can_Never_Be_Null (Etype (Prev)) or else Nkind (Prev) = N_Attribute_Reference
then then
Cond := null;
Make_Op_Eq (Loc,
Left_Opnd => Duplicate_Subexpr_No_Checks (Prev), -- Suppress null checks when passing to access parameters of Java
Right_Opnd => Make_Null (Loc)); -- subprograms. (Should this be done for other foreign conventions
Insert_Action (Prev, -- as well ???)
Make_Raise_Constraint_Error (Loc,
Condition => Cond, elsif Convention (Subp) = Convention_Java then
Reason => CE_Access_Parameter_Is_Null)); null;
else
Install_Null_Excluding_Check (Prev);
end if;
end if; end if;
-- Perform appropriate validity checks on parameters that -- Perform appropriate validity checks on parameters that
...@@ -1974,7 +1984,6 @@ package body Exp_Ch6 is ...@@ -1974,7 +1984,6 @@ package body Exp_Ch6 is
or else Is_Generic_Instance (Parent_Subp) or else Is_Generic_Instance (Parent_Subp)
then then
while Present (Formal) loop while Present (Formal) loop
if Etype (Formal) /= Etype (Parent_Formal) if Etype (Formal) /= Etype (Parent_Formal)
and then Is_Scalar_Type (Etype (Formal)) and then Is_Scalar_Type (Etype (Formal))
and then Ekind (Formal) = E_In_Parameter and then Ekind (Formal) = E_In_Parameter
...@@ -1989,8 +1998,8 @@ package body Exp_Ch6 is ...@@ -1989,8 +1998,8 @@ package body Exp_Ch6 is
Enable_Range_Check (Actual); Enable_Range_Check (Actual);
elsif Is_Access_Type (Etype (Formal)) elsif Is_Access_Type (Etype (Formal))
and then Base_Type (Etype (Parent_Formal)) and then Base_Type (Etype (Parent_Formal)) /=
/= Base_Type (Etype (Actual)) Base_Type (Etype (Actual))
then then
if Ekind (Formal) /= E_In_Parameter then if Ekind (Formal) /= E_In_Parameter then
Rewrite (Actual, Rewrite (Actual,
...@@ -2161,9 +2170,10 @@ package body Exp_Ch6 is ...@@ -2161,9 +2170,10 @@ package body Exp_Ch6 is
-------------------------- --------------------------
function In_Unfrozen_Instance return Boolean is function In_Unfrozen_Instance return Boolean is
S : Entity_Id := Scop; S : Entity_Id;
begin begin
S := Scop;
while Present (S) while Present (S)
and then S /= Standard_Standard and then S /= Standard_Standard
loop loop
...@@ -2183,10 +2193,12 @@ package body Exp_Ch6 is ...@@ -2183,10 +2193,12 @@ package body Exp_Ch6 is
-- Start of processing for Inlined_Subprogram -- Start of processing for Inlined_Subprogram
begin begin
-- Verify that the body to inline has already been seen, -- Verify that the body to inline has already been seen, and
-- and that if the body is in the current unit the inlining -- that if the body is in the current unit the inlining does
-- does not occur earlier. This avoids order-of-elaboration -- not occur earlier. This avoids order-of-elaboration problems
-- problems in gigi. -- in the back end.
-- This should be documented in sinfo/einfo ???
if No (Spec) if No (Spec)
or else Nkind (Spec) /= N_Subprogram_Declaration or else Nkind (Spec) /= N_Subprogram_Declaration
...@@ -2683,15 +2695,14 @@ package body Exp_Ch6 is ...@@ -2683,15 +2695,14 @@ package body Exp_Ch6 is
Original_Assignment : constant Node_Id := Parent (N); Original_Assignment : constant Node_Id := Parent (N);
begin begin
-- Preserve the original assignment node to keep the -- Preserve the original assignment node to keep the complete
-- complete assignment subtree consistent enough for -- assignment subtree consistent enough for Analyze_Assignment
-- Analyze_Assignment to proceed (specifically, the -- to proceed (specifically, the original Lhs node must still
-- original Lhs node must still have an assignment -- have an assignment statement as its parent).
-- statement as its parent).
-- We cannot rely on Original_Node to go back from the -- We cannot rely on Original_Node to go back from the block
-- block node to the assignment node, because the -- node to the assignment node, because the assignment might
-- assignment might already be a rewrite substitution. -- already be a rewrite substitution.
Discard_Node (Relocate_Node (Original_Assignment)); Discard_Node (Relocate_Node (Original_Assignment));
Rewrite (Original_Assignment, Blk); Rewrite (Original_Assignment, Blk);
...@@ -2741,8 +2752,7 @@ package body Exp_Ch6 is ...@@ -2741,8 +2752,7 @@ package body Exp_Ch6 is
if Nkind (N) = N_Identifier if Nkind (N) = N_Identifier
and then Present (Entity (N)) and then Present (Entity (N))
-- The original node's entity points to the one in the -- Original node's entity points to the one in the copied body
-- copied body.
and then Nkind (Entity (N)) = N_Identifier and then Nkind (Entity (N)) = N_Identifier
and then Present (Entity (Entity (N))) and then Present (Entity (Entity (N)))
...@@ -2781,8 +2791,8 @@ package body Exp_Ch6 is ...@@ -2781,8 +2791,8 @@ package body Exp_Ch6 is
-- Check for special case of To_Address call, and if so, just do an -- Check for special case of To_Address call, and if so, just do an
-- unchecked conversion instead of expanding the call. Not only is this -- unchecked conversion instead of expanding the call. Not only is this
-- more efficient, but it also avoids problem with order of elaboration -- more efficient, but it also avoids problem with order of elaboration
-- when address clauses are inlined (address expr elaborated at wrong -- when address clauses are inlined (address expression elaborated at
-- point). -- wrong point).
if Subp = RTE (RE_To_Address) then if Subp = RTE (RE_To_Address) then
Rewrite (N, Rewrite (N,
...@@ -2848,15 +2858,14 @@ package body Exp_Ch6 is ...@@ -2848,15 +2858,14 @@ package body Exp_Ch6 is
Ret_Type := Etype (Subp); Ret_Type := Etype (Subp);
end if; end if;
F := First_Formal (Subp);
A := First_Actual (N);
-- Create temporaries for the actuals that are expressions, or that -- Create temporaries for the actuals that are expressions, or that
-- are scalars and require copying to preserve semantics. -- are scalars and require copying to preserve semantics.
F := First_Formal (Subp);
A := First_Actual (N);
while Present (F) loop while Present (F) loop
if Present (Renamed_Object (F)) then if Present (Renamed_Object (F)) then
Error_Msg_N (" cannot inline call to recursive subprogram", N); Error_Msg_N ("cannot inline call to recursive subprogram", N);
return; return;
end if; end if;
...@@ -3061,7 +3070,6 @@ package body Exp_Ch6 is ...@@ -3061,7 +3070,6 @@ package body Exp_Ch6 is
-- Cleanup mapping between formals and actuals for other expansions -- Cleanup mapping between formals and actuals for other expansions
F := First_Formal (Subp); F := First_Formal (Subp);
while Present (F) loop while Present (F) loop
Set_Renamed_Object (F, Empty); Set_Renamed_Object (F, Empty);
Next_Formal (F); Next_Formal (F);
...@@ -3090,7 +3098,7 @@ package body Exp_Ch6 is ...@@ -3090,7 +3098,7 @@ package body Exp_Ch6 is
--------------------------- ---------------------------
function Returned_By_Reference return Boolean is function Returned_By_Reference return Boolean is
S : Entity_Id := Current_Scope; S : Entity_Id;
begin begin
if Is_Return_By_Reference_Type (Typ) then if Is_Return_By_Reference_Type (Typ) then
...@@ -3104,6 +3112,7 @@ package body Exp_Ch6 is ...@@ -3104,6 +3112,7 @@ package body Exp_Ch6 is
-- Verify that the return type of the enclosing function has the -- Verify that the return type of the enclosing function has the
-- same constrained status as that of the expression. -- same constrained status as that of the expression.
S := Current_Scope;
while Ekind (S) /= E_Function loop while Ekind (S) /= E_Function loop
S := Scope (S); S := Scope (S);
end loop; end loop;
...@@ -3202,9 +3211,9 @@ package body Exp_Ch6 is ...@@ -3202,9 +3211,9 @@ package body Exp_Ch6 is
-- object is not classwide. -- object is not classwide.
Proc := Entity (Name (Parent (N))); Proc := Entity (Name (Parent (N)));
F := First_Formal (Proc); F := First_Formal (Proc);
A := First_Actual (Parent (N)); A := First_Actual (Parent (N));
while A /= N loop while A /= N loop
Next_Formal (F); Next_Formal (F);
Next_Actual (A); Next_Actual (A);
...@@ -3535,9 +3544,10 @@ package body Exp_Ch6 is ...@@ -3535,9 +3544,10 @@ package body Exp_Ch6 is
and then not Has_Pragma_Pure_Function (Spec_Id) and then not Has_Pragma_Pure_Function (Spec_Id)
then then
declare declare
F : Entity_Id := First_Formal (Spec_Id); F : Entity_Id;
begin begin
F := First_Formal (Spec_Id);
while Present (F) loop while Present (F) loop
if Is_Descendent_Of_Address (Etype (F)) then if Is_Descendent_Of_Address (Etype (F)) then
Set_Is_Pure (Spec_Id, False); Set_Is_Pure (Spec_Id, False);
...@@ -3558,7 +3568,7 @@ package body Exp_Ch6 is ...@@ -3558,7 +3568,7 @@ package body Exp_Ch6 is
if Init_Or_Norm_Scalars and then Is_Subprogram (Spec_Id) then if Init_Or_Norm_Scalars and then Is_Subprogram (Spec_Id) then
declare declare
F : Entity_Id := First_Formal (Spec_Id); F : Entity_Id;
V : constant Boolean := Validity_Checks_On; V : constant Boolean := Validity_Checks_On;
begin begin
...@@ -3570,6 +3580,7 @@ package body Exp_Ch6 is ...@@ -3570,6 +3580,7 @@ package body Exp_Ch6 is
-- Loop through formals -- Loop through formals
F := First_Formal (Spec_Id);
while Present (F) loop while Present (F) loop
if Is_Scalar_Type (Etype (F)) if Is_Scalar_Type (Etype (F))
and then Ekind (F) = E_Out_Parameter and then Ekind (F) = E_Out_Parameter
...@@ -3589,9 +3600,9 @@ package body Exp_Ch6 is ...@@ -3589,9 +3600,9 @@ package body Exp_Ch6 is
Scop := Scope (Spec_Id); Scop := Scope (Spec_Id);
-- Add discriminal renamings to protected subprograms. -- Add discriminal renamings to protected subprograms. Install new
-- Install new discriminals for expansion of the next -- discriminals for expansion of the next subprogram of this protected
-- subprogram of this protected type, if any. -- type, if any.
if Is_List_Member (N) if Is_List_Member (N)
and then Present (Parent (List_Containing (N))) and then Present (Parent (List_Containing (N)))
...@@ -3602,9 +3613,8 @@ package body Exp_Ch6 is ...@@ -3602,9 +3613,8 @@ package body Exp_Ch6 is
Add_Private_Declarations (Declarations (N), Scop, Name_uObject, Loc); Add_Private_Declarations (Declarations (N), Scop, Name_uObject, Loc);
-- Associate privals and discriminals with the next protected -- Associate privals and discriminals with the next protected
-- operation body to be expanded. These are used to expand -- operation body to be expanded. These are used to expand references
-- references to private data objects and discriminants, -- to private data objects and discriminants, respectively.
-- respectively.
Next_Op := Next_Protected_Operation (N); Next_Op := Next_Protected_Operation (N);
...@@ -3633,7 +3643,7 @@ package body Exp_Ch6 is ...@@ -3633,7 +3643,7 @@ package body Exp_Ch6 is
end if; end if;
-- Returns_By_Ref flag is normally set when the subprogram is frozen -- Returns_By_Ref flag is normally set when the subprogram is frozen
-- but subprograms with no specs are not frozen -- but subprograms with no specs are not frozen.
declare declare
Typ : constant Entity_Id := Etype (Spec_Id); Typ : constant Entity_Id := Etype (Spec_Id);
...@@ -3665,7 +3675,6 @@ package body Exp_Ch6 is ...@@ -3665,7 +3675,6 @@ package body Exp_Ch6 is
if Present (Exception_Handlers (H)) then if Present (Exception_Handlers (H)) then
Except_H := First_Non_Pragma (Exception_Handlers (H)); Except_H := First_Non_Pragma (Exception_Handlers (H));
while Present (Except_H) loop while Present (Except_H) loop
Add_Return (Statements (Except_H)); Add_Return (Statements (Except_H));
Next_Non_Pragma (Except_H); Next_Non_Pragma (Except_H);
...@@ -3742,7 +3751,6 @@ package body Exp_Ch6 is ...@@ -3742,7 +3751,6 @@ package body Exp_Ch6 is
begin begin
Formal := First_Formal (Spec_Id); Formal := First_Formal (Spec_Id);
while Present (Formal) loop while Present (Formal) loop
Floc := Sloc (Formal); Floc := Sloc (Formal);
...@@ -3769,18 +3777,6 @@ package body Exp_Ch6 is ...@@ -3769,18 +3777,6 @@ package body Exp_Ch6 is
Expand_Thread_Body; Expand_Thread_Body;
end if; end if;
-- If the subprogram does not have pending instantiations, then we
-- must generate the subprogram descriptor now, since the code for
-- the subprogram is complete, and this is our last chance. However
-- if there are pending instantiations, then the code is not
-- complete, and we will delay the generation.
if Is_Subprogram (Spec_Id)
and then not Delay_Subprogram_Descriptors (Spec_Id)
then
Generate_Subprogram_Descriptor_For_Subprogram (N, Spec_Id);
end if;
-- Set to encode entity names in package body before gigi is called -- Set to encode entity names in package body before gigi is called
Qualify_Entity_Names (N); Qualify_Entity_Names (N);
...@@ -3818,8 +3814,8 @@ package body Exp_Ch6 is ...@@ -3818,8 +3814,8 @@ package body Exp_Ch6 is
Prot_Id : Entity_Id; Prot_Id : Entity_Id;
begin begin
-- Deal with case of protected subprogram. Do not generate -- Deal with case of protected subprogram. Do not generate protected
-- protected operation if operation is flagged as eliminated. -- operation if operation is flagged as eliminated.
if Is_List_Member (N) if Is_List_Member (N)
and then Present (Parent (List_Containing (N))) and then Present (Parent (List_Containing (N)))
...@@ -3833,7 +3829,7 @@ package body Exp_Ch6 is ...@@ -3833,7 +3829,7 @@ package body Exp_Ch6 is
Make_Subprogram_Declaration (Loc, Make_Subprogram_Declaration (Loc,
Specification => Specification =>
Build_Protected_Sub_Specification Build_Protected_Sub_Specification
(N, Scop, Unprotected => True)); (N, Scop, Unprotected_Mode));
-- The protected subprogram is declared outside of the protected -- The protected subprogram is declared outside of the protected
-- body. Given that the body has frozen all entities so far, we -- body. Given that the body has frozen all entities so far, we
...@@ -3907,18 +3903,16 @@ package body Exp_Ch6 is ...@@ -3907,18 +3903,16 @@ package body Exp_Ch6 is
Rec := Make_Identifier (Loc, Name_uObject); Rec := Make_Identifier (Loc, Name_uObject);
Set_Etype (Rec, Corresponding_Record_Type (Scop)); Set_Etype (Rec, Corresponding_Record_Type (Scop));
-- Find enclosing protected operation, and retrieve its first -- Find enclosing protected operation, and retrieve its first parameter,
-- parameter, which denotes the enclosing protected object. -- which denotes the enclosing protected object. If the enclosing
-- If the enclosing operation is an entry, we are immediately -- operation is an entry, we are immediately within the protected body,
-- within the protected body, and we can retrieve the object -- and we can retrieve the object from the service entries procedure. A
-- from the service entries procedure. A barrier function has -- barrier function has has the same signature as an entry. A barrier
-- has the same signature as an entry. A barrier function is -- function is compiled within the protected object, but unlike
-- compiled within the protected object, but unlike protected -- protected operations its never needs locks, so that its protected
-- operations its never needs locks, so that its protected body -- body subprogram points to itself.
-- subprogram points to itself.
Proc := Current_Scope; Proc := Current_Scope;
while Present (Proc) while Present (Proc)
and then Scope (Proc) /= Scop and then Scope (Proc) /= Scop
loop loop
...@@ -3946,17 +3940,16 @@ package body Exp_Ch6 is ...@@ -3946,17 +3940,16 @@ package body Exp_Ch6 is
Set_Entity (Rec, Param); Set_Entity (Rec, Param);
-- Rec is a reference to an entity which will not be in scope -- Rec is a reference to an entity which will not be in scope when
-- when the call is reanalyzed, and needs no further analysis. -- the call is reanalyzed, and needs no further analysis.
Set_Analyzed (Rec); Set_Analyzed (Rec);
else else
-- Entry or barrier function for entry body. -- Entry or barrier function for entry body. The first parameter of
-- The first parameter of the entry body procedure is a -- the entry body procedure is pointer to the object. We create a
-- pointer to the object. We create a local variable -- local variable of the proper type, duplicating what is done to
-- of the proper type, duplicating what is done to define -- define _object later on.
-- _object later on.
declare declare
Decls : List_Id; Decls : List_Id;
...@@ -3982,9 +3975,8 @@ package body Exp_Ch6 is ...@@ -3982,9 +3975,8 @@ package body Exp_Ch6 is
Unchecked_Convert_To (Obj_Ptr, Unchecked_Convert_To (Obj_Ptr,
New_Occurrence_Of (Param, Loc))); New_Occurrence_Of (Param, Loc)));
-- Analyze new actual. Other actuals in calls are already -- Analyze new actual. Other actuals in calls are already analyzed
-- analyzed and the list of actuals is not renalyzed after -- and the list of actuals is not renalyzed after rewriting.
-- rewriting.
Set_Parent (Rec, N); Set_Parent (Rec, N);
Analyze (Rec); Analyze (Rec);
...@@ -4065,7 +4057,7 @@ package body Exp_Ch6 is ...@@ -4065,7 +4057,7 @@ package body Exp_Ch6 is
procedure Check_Overriding_Inherited_Interfaces (E : Entity_Id); procedure Check_Overriding_Inherited_Interfaces (E : Entity_Id);
-- (Ada 2005): Check if the primitive E covers some interface already -- (Ada 2005): Check if the primitive E covers some interface already
-- implemented by some ancestor of the tagged-type associated with E -- implemented by some ancestor of the tagged-type associated with E.
procedure Register_Interface_DT_Entry procedure Register_Interface_DT_Entry
(Prim : Entity_Id; (Prim : Entity_Id;
...@@ -4114,29 +4106,56 @@ package body Exp_Ch6 is ...@@ -4114,29 +4106,56 @@ package body Exp_Ch6 is
while Present (Elmt) loop while Present (Elmt) loop
Prim_Op := Node (Elmt); Prim_Op := Node (Elmt);
if DT_Position (Prim_Op) = DT_Position (E) if Chars (Prim_Op) = Chars (E)
and then Type_Conformant
(New_Id => Prim_Op,
Old_Id => E,
Skip_Controlling_Formals => True)
and then DT_Position (Prim_Op) = DT_Position (E)
and then Etype (DTC_Entity (Prim_Op)) = RTE (RE_Tag) and then Etype (DTC_Entity (Prim_Op)) = RTE (RE_Tag)
and then not Present (Abstract_Interface_Alias (Prim_Op)) and then not Present (Abstract_Interface_Alias (Prim_Op))
then then
if Overriden_Op /= Empty then if Overriden_Op = Empty then
raise Program_Error; Overriden_Op := Prim_Op;
end if;
-- Additional check to ensure that if two candidates have
-- been found then they refer to the same subprogram.
Overriden_Op := Prim_Op; else
declare
A1 : Entity_Id;
A2 : Entity_Id;
begin
A1 := Overriden_Op;
while Present (Alias (A1)) loop
A1 := Alias (A1);
end loop;
A2 := Prim_Op;
while Present (Alias (A2)) loop
A2 := Alias (A2);
end loop;
if A1 /= A2 then
raise Program_Error;
end if;
end;
end if;
end if; end if;
Next_Elmt (Elmt); Next_Elmt (Elmt);
end loop; end loop;
-- if not found this is the first overriding of some -- If not found this is the first overriding of some abstract
-- abstract interface -- interface.
if Overriden_Op /= Empty then if Overriden_Op /= Empty then
Elmt := First_Elmt (Primitive_Operations (Typ));
-- Find the entries associated with interfaces that are -- Find the entries associated with interfaces that are
-- alias of this primitive operation in the ancestor -- alias of this primitive operation in the ancestor.
Elmt := First_Elmt (Primitive_Operations (Typ));
while Present (Elmt) loop while Present (Elmt) loop
Prim_Op := Node (Elmt); Prim_Op := Node (Elmt);
...@@ -4178,7 +4197,7 @@ package body Exp_Ch6 is ...@@ -4178,7 +4197,7 @@ package body Exp_Ch6 is
Iface => Iface_Typ); Iface => Iface_Typ);
-- Generate the code of the thunk only when this primitive -- Generate the code of the thunk only when this primitive
-- operation is associated with a secondary dispatch table -- operation is associated with a secondary dispatch table.
if Etype (Iface_Tag) = RTE (RE_Interface_Tag) then if Etype (Iface_Tag) = RTE (RE_Interface_Tag) then
Thunk_Id := Make_Defining_Identifier (Loc, Thunk_Id := Make_Defining_Identifier (Loc,
...@@ -4188,7 +4207,7 @@ package body Exp_Ch6 is ...@@ -4188,7 +4207,7 @@ package body Exp_Ch6 is
(N => Prim, (N => Prim,
Thunk_Alias => Alias (Prim), Thunk_Alias => Alias (Prim),
Thunk_Id => Thunk_Id, Thunk_Id => Thunk_Id,
Iface_Tag => Iface_Tag); Thunk_Tag => Iface_Tag);
Insert_After (N, New_Thunk); Insert_After (N, New_Thunk);
...@@ -4238,7 +4257,7 @@ package body Exp_Ch6 is ...@@ -4238,7 +4257,7 @@ package body Exp_Ch6 is
(N => Ancestor_Iface_Prim, (N => Ancestor_Iface_Prim,
Thunk_Alias => Prim_Op, Thunk_Alias => Prim_Op,
Thunk_Id => Thunk_Id, Thunk_Id => Thunk_Id,
Iface_Tag => Iface_Tag); Thunk_Tag => Iface_Tag);
Insert_After (N, New_Thunk); Insert_After (N, New_Thunk);
...@@ -4279,7 +4298,7 @@ package body Exp_Ch6 is ...@@ -4279,7 +4298,7 @@ package body Exp_Ch6 is
else else
-- Ada 2005 (AI-251): Check if this entry corresponds with -- Ada 2005 (AI-251): Check if this entry corresponds with
-- a subprogram that covers an abstract interface type -- a subprogram that covers an abstract interface type.
if Present (Abstract_Interface_Alias (E)) then if Present (Abstract_Interface_Alias (E)) then
Register_Interface_DT_Entry (E); Register_Interface_DT_Entry (E);
...@@ -4296,7 +4315,7 @@ package body Exp_Ch6 is ...@@ -4296,7 +4315,7 @@ package body Exp_Ch6 is
-- Mark functions that return by reference. Note that it cannot be -- Mark functions that return by reference. Note that it cannot be
-- part of the normal semantic analysis of the spec since the -- part of the normal semantic analysis of the spec since the
-- underlying returned type may not be known yet (for private types) -- underlying returned type may not be known yet (for private types).
declare declare
Typ : constant Entity_Id := Etype (E); Typ : constant Entity_Id := Etype (E);
......
...@@ -89,7 +89,7 @@ package Exp_Dbug is ...@@ -89,7 +89,7 @@ package Exp_Dbug is
-- x -- x
-- y.z -- y.z
-- The separating dots are translated into double underscores. -- The separating dots are translated into double underscores
----------------------------- -----------------------------
-- Handling of Overloading -- -- Handling of Overloading --
...@@ -385,6 +385,28 @@ package Exp_Dbug is ...@@ -385,6 +385,28 @@ package Exp_Dbug is
-- lock_update1sE -- lock_update1sE
-- lock_udpate2sB -- lock_udpate2sB
-- If the protected type implements at least one interface, the
-- following additional operations are created:
-- lock_get
-- lock_set
-- These operations are used to ensure overriding of interface level
-- subprograms and proper dispatching on interface class-wide objects.
-- The bodies of these operations contain calls to their respective
-- protected versions:
-- function lock_get return Integer is
-- begin
-- return lock_getP;
-- end lock_get;
-- procedure lock_set (X : Integer) is
-- begin
-- lock_setP (X);
-- end lock_set;
---------------------------------------------------- ----------------------------------------------------
-- Conversion between Entities and External Names -- -- Conversion between Entities and External Names --
---------------------------------------------------- ----------------------------------------------------
...@@ -686,9 +708,9 @@ package Exp_Dbug is ...@@ -686,9 +708,9 @@ package Exp_Dbug is
-- follows. In this description, let P represent the current -- follows. In this description, let P represent the current
-- bit position in the record. -- bit position in the record.
-- 1. Initialize P to 0. -- 1. Initialize P to 0
-- 2. For each field in the record, -- 2. For each field in the record:
-- 2a. If an alignment is given (see below), then round P -- 2a. If an alignment is given (see below), then round P
-- up, if needed, to the next multiple of that alignment. -- up, if needed, to the next multiple of that alignment.
...@@ -697,7 +719,7 @@ package Exp_Dbug is ...@@ -697,7 +719,7 @@ package Exp_Dbug is
-- amount (that is, treat it as an offset from the end of the -- amount (that is, treat it as an offset from the end of the
-- preceding record). -- preceding record).
-- 2c. Assign P as the actual position of the field. -- 2c. Assign P as the actual position of the field
-- 2d. Compute the length, L, of the represented field (see below) -- 2d. Compute the length, L, of the represented field (see below)
-- and compute P'=P+L. Unless the field represents a variant part -- and compute P'=P+L. Unless the field represents a variant part
...@@ -963,7 +985,7 @@ package Exp_Dbug is ...@@ -963,7 +985,7 @@ package Exp_Dbug is
-- name of the parent unit, to disambiguate child units with the same -- name of the parent unit, to disambiguate child units with the same
-- simple name and (of necessity) different parents. -- simple name and (of necessity) different parents.
-- Note: subprogram renamings are not encoded at the present time. -- Note: subprogram renamings are not encoded at the present time
-- The type is an enumeration type with a single enumeration literal -- The type is an enumeration type with a single enumeration literal
-- that is an identifier which describes the renamed variable. -- that is an identifier which describes the renamed variable.
......
...@@ -53,6 +53,11 @@ package body Lib.Load is ...@@ -53,6 +53,11 @@ package body Lib.Load is
-- Local Subprograms -- -- Local Subprograms --
----------------------- -----------------------
function From_Limited_With_Chain (Lim : Boolean) return Boolean;
-- Check whether a possible circular dependence includes units that
-- have been loaded through limited_with clauses, in which case there
-- is no real circularity.
function Spec_Is_Irrelevant function Spec_Is_Irrelevant
(Spec_Unit : Unit_Number_Type; (Spec_Unit : Unit_Number_Type;
Body_Unit : Unit_Number_Type) return Boolean; Body_Unit : Unit_Number_Type) return Boolean;
...@@ -165,6 +170,30 @@ package body Lib.Load is ...@@ -165,6 +170,30 @@ package body Lib.Load is
return Unum; return Unum;
end Create_Dummy_Package_Unit; end Create_Dummy_Package_Unit;
-----------------------------
-- From_Limited_With_Chain --
-----------------------------
function From_Limited_With_Chain (Lim : Boolean) return Boolean is
begin
-- True if the current load operation is through a limited_with clause
if Lim then
return True;
-- Examine the Load_Stack to locate any previous Limited_with clause
elsif Load_Stack.Last - 1 > Load_Stack.First then
for U in Load_Stack.First .. Load_Stack.Last - 1 loop
if Load_Stack.Table (U).From_Limited_With then
return True;
end if;
end loop;
end if;
return False;
end From_Limited_With_Chain;
---------------- ----------------
-- Initialize -- -- Initialize --
---------------- ----------------
...@@ -193,7 +222,7 @@ package body Lib.Load is ...@@ -193,7 +222,7 @@ package body Lib.Load is
begin begin
Load_Stack.Increment_Last; Load_Stack.Increment_Last;
Load_Stack.Table (Load_Stack.Last) := Main_Unit; Load_Stack.Table (Load_Stack.Last) := (Main_Unit, False);
-- Initialize unit table entry for Main_Unit. Note that we don't know -- Initialize unit table entry for Main_Unit. Note that we don't know
-- the unit name yet, that gets filled in when the parser parses the -- the unit name yet, that gets filled in when the parser parses the
...@@ -465,10 +494,11 @@ package body Lib.Load is ...@@ -465,10 +494,11 @@ package body Lib.Load is
end loop; end loop;
end if; end if;
-- If we are proceeding with load, then make load stack entry -- If we are proceeding with load, then make load stack entry,
-- and indicate the kind of with_clause responsible for the load.
Load_Stack.Increment_Last; Load_Stack.Increment_Last;
Load_Stack.Table (Load_Stack.Last) := Unum; Load_Stack.Table (Load_Stack.Last) := (Unum, From_Limited_With);
-- Case of entry already in table -- Case of entry already in table
...@@ -489,7 +519,7 @@ package body Lib.Load is ...@@ -489,7 +519,7 @@ package body Lib.Load is
or else Acts_As_Spec (Units.Table (Unum).Cunit)) or else Acts_As_Spec (Units.Table (Unum).Cunit))
and then (Nkind (Error_Node) /= N_With_Clause and then (Nkind (Error_Node) /= N_With_Clause
or else not Limited_Present (Error_Node)) or else not Limited_Present (Error_Node))
and then not From_Limited_With and then not From_Limited_With_Chain (From_Limited_With)
then then
if Debug_Flag_L then if Debug_Flag_L then
Write_Str (" circular dependency encountered"); Write_Str (" circular dependency encountered");
...@@ -733,8 +763,10 @@ package body Lib.Load is ...@@ -733,8 +763,10 @@ package body Lib.Load is
if Load_Stack.Last - 1 > Load_Stack.First then if Load_Stack.Last - 1 > Load_Stack.First then
for U in Load_Stack.First .. Load_Stack.Last - 1 loop for U in Load_Stack.First .. Load_Stack.Last - 1 loop
Error_Msg_Unit_1 := Unit_Name (Load_Stack.Table (U)); Error_Msg_Unit_1 :=
Error_Msg_Unit_2 := Unit_Name (Load_Stack.Table (U + 1)); Unit_Name (Load_Stack.Table (U).Unit_Number);
Error_Msg_Unit_2 :=
Unit_Name (Load_Stack.Table (U + 1).Unit_Number);
Error_Msg ("$ depends on $!", Load_Msg_Sloc); Error_Msg ("$ depends on $!", Load_Msg_Sloc);
end loop; end loop;
end if; end if;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- S p e c -- -- S p e c --
-- -- -- --
-- Copyright (C) 1992-2004 Free Software Foundation, Inc. -- -- Copyright (C) 1992-2005 Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- 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- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -239,11 +239,6 @@ package Lib is ...@@ -239,11 +239,6 @@ package Lib is
-- Main_Unit is a body with a separate spec, in which case it is the -- Main_Unit is a body with a separate spec, in which case it is the
-- entity for the spec. -- entity for the spec.
Unit_Exception_Table_Present : Boolean;
-- Set true if a unit exception table is present for the unit (i.e.
-- zero cost exception handling is active and there is at least one
-- subprogram in the extended unit).
----------------- -----------------
-- Units Table -- -- Units Table --
----------------- -----------------
...@@ -623,7 +618,7 @@ package Lib is ...@@ -623,7 +618,7 @@ package Lib is
function Generic_Separately_Compiled function Generic_Separately_Compiled
(Sfile : File_Name_Type) return Boolean; (Sfile : File_Name_Type) return Boolean;
-- Same as the previous function, but works directly on a unit file name. -- Same as the previous function, but works directly on a unit file name
private private
pragma Inline (Cunit); pragma Inline (Cunit);
...@@ -722,16 +717,23 @@ private ...@@ -722,16 +717,23 @@ private
type Unit_Ref_Table is array (Pos range <>) of Unit_Number_Type; type Unit_Ref_Table is array (Pos range <>) of Unit_Number_Type;
-- Type to hold list of indirect references to unit number table -- Type to hold list of indirect references to unit number table
-- The Load_Stack table contains a list of unit numbers (indexes into the type Load_Stack_Entry is record
-- unit table) of units being loaded on a single dependency chain. The Unit_Number : Unit_Number_Type;
-- First entry is the main unit. The second entry, if present is a unit From_Limited_With : Boolean;
-- on which the first unit depends, etc. This stack is used to generate end record;
-- error messages showing the dependency chain if a file is not found.
-- The Load function makes an entry in this table when it is called, and -- The Load_Stack table contains a list of unit numbers (indices into the
-- removes the entry just before it returns. -- unit table) of units being loaded on a single dependency chain, and a
-- flag to indicate whether this unit is loaded through a limited_with
-- clause. The First entry is the main unit. The second entry, if present
-- is a unit on which the first unit depends, etc. This stack is used to
-- generate error messages showing the dependency chain if a file is not
-- found, or whether a true circular dependency exists. The Load_Unit
-- function makes an entry in this table when it is called, and removes
-- the entry just before it returns.
package Load_Stack is new Table.Table ( package Load_Stack is new Table.Table (
Table_Component_Type => Unit_Number_Type, Table_Component_Type => Load_Stack_Entry,
Table_Index_Type => Nat, Table_Index_Type => Nat,
Table_Low_Bound => 0, Table_Low_Bound => 0,
Table_Initial => Alloc.Load_Stack_Initial, Table_Initial => Alloc.Load_Stack_Initial,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment