Commit 294ccb21 by Robert Dewar Committed by Arnaud Charlet

sem_ch8.adb (Analyze_Subprogram_Renaming): Special error message for renaming…

sem_ch8.adb (Analyze_Subprogram_Renaming): Special error message for renaming entry as subprogram using rename-as-body if...

2007-12-06  Robert Dewar  <dewar@adacore.com>
	    Ed Schonberg  <schonberg@adacore.com>

	* sem_ch8.adb (Analyze_Subprogram_Renaming): Special error message for
	renaming entry as subprogram using rename-as-body if subprogram spec
	frozen.
	(Use_One_Type): The clause is legal on an access type whose designated
	type has a limited view.
	(Find_Direct_Name): Use Namet.Sp.Is_Bad_Spelling_Of function
	(Find_Expanded_Name): Use Namet.Sp.Is_Bad_Spelling_Of function
	(Analyze_Renamed_Primitive_Operation): new procedure to determine the
	operation denoted by a selected component.
	(Analyze_Renamed_Entry): Resolve the prefix of the entry name, because
	it can be an expression, possibly overloaded, that returns a task or
	an access to one.

From-SVN: r130854
parent d469eabe
...@@ -37,6 +37,7 @@ with Lib; use Lib; ...@@ -37,6 +37,7 @@ with Lib; use Lib;
with Lib.Load; use Lib.Load; with Lib.Load; use Lib.Load;
with Lib.Xref; use Lib.Xref; with Lib.Xref; use Lib.Xref;
with Namet; use Namet; with Namet; use Namet;
with Namet.Sp; use Namet.Sp;
with Nlists; use Nlists; with Nlists; use Nlists;
with Nmake; use Nmake; with Nmake; use Nmake;
with Opt; use Opt; with Opt; use Opt;
...@@ -64,8 +65,6 @@ with Table; ...@@ -64,8 +65,6 @@ with Table;
with Tbuild; use Tbuild; with Tbuild; use Tbuild;
with Uintp; use Uintp; with Uintp; use Uintp;
with GNAT.Spelling_Checker; use GNAT.Spelling_Checker;
package body Sem_Ch8 is package body Sem_Ch8 is
------------------------------------ ------------------------------------
...@@ -388,6 +387,14 @@ package body Sem_Ch8 is ...@@ -388,6 +387,14 @@ package body Sem_Ch8 is
-- Used when the renamed entity is an indexed component. The prefix must -- Used when the renamed entity is an indexed component. The prefix must
-- denote an entry family. -- denote an entry family.
procedure Analyze_Renamed_Primitive_Operation
(N : Node_Id;
New_S : Entity_Id;
Is_Body : Boolean);
-- If the renamed entity in a subprogram renaming is a primitive operation
-- or a class-wide operation in prefix form, save the target object, which
-- must be added to the list of actuals in any subsequent call.
function Applicable_Use (Pack_Name : Node_Id) return Boolean; function Applicable_Use (Pack_Name : Node_Id) return Boolean;
-- Common code to Use_One_Package and Set_Use, to determine whether -- Common code to Use_One_Package and Set_Use, to determine whether
-- use clause must be processed. Pack_Name is an entity name that -- use clause must be processed. Pack_Name is an entity name that
...@@ -974,7 +981,7 @@ package body Sem_Ch8 is ...@@ -974,7 +981,7 @@ package body Sem_Ch8 is
end if; end if;
-- Apply Text_IO kludge here, since we may be renaming one of the -- Apply Text_IO kludge here, since we may be renaming one of the
-- children of Text_IO -- children of Text_IO.
Text_IO_Kludge (Name (N)); Text_IO_Kludge (Name (N));
...@@ -1014,6 +1021,8 @@ package body Sem_Ch8 is ...@@ -1014,6 +1021,8 @@ package body Sem_Ch8 is
Set_Ekind (New_P, E_Package); Set_Ekind (New_P, E_Package);
Set_Etype (New_P, Standard_Void_Type); Set_Etype (New_P, Standard_Void_Type);
-- Here for OK package renaming
else else
-- Entities in the old package are accessible through the renaming -- Entities in the old package are accessible through the renaming
-- entity. The simplest implementation is to have both packages share -- entity. The simplest implementation is to have both packages share
...@@ -1036,6 +1045,24 @@ package body Sem_Ch8 is ...@@ -1036,6 +1045,24 @@ package body Sem_Ch8 is
Check_Library_Unit_Renaming (N, Old_P); Check_Library_Unit_Renaming (N, Old_P);
Generate_Reference (Old_P, Name (N)); Generate_Reference (Old_P, Name (N));
-- If the renaming is in the visible part of a package, then we set
-- In_Package_Spec for the renamed package, to prevent giving
-- warnings about no entities referenced. Such a warning would be
-- overenthusiastic, since clients can see entities in the renamed
-- package via the visible package renaming.
declare
Ent : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
begin
if Ekind (Ent) = E_Package
and then not In_Private_Part (Ent)
and then In_Extended_Main_Source_Unit (N)
and then Ekind (Old_P) = E_Package
then
Set_Renamed_In_Spec (Old_P);
end if;
end;
-- If this is the renaming declaration of a package instantiation -- If this is the renaming declaration of a package instantiation
-- within itself, it is the declaration that ends the list of actuals -- within itself, it is the declaration that ends the list of actuals
-- for the instantiation. At this point, the subtypes that rename -- for the instantiation. At this point, the subtypes that rename
...@@ -1084,7 +1111,6 @@ package body Sem_Ch8 is ...@@ -1084,7 +1111,6 @@ package body Sem_Ch8 is
end; end;
end if; end if;
end if; end if;
end Analyze_Package_Renaming; end Analyze_Package_Renaming;
------------------------------- -------------------------------
...@@ -1210,6 +1236,11 @@ package body Sem_Ch8 is ...@@ -1210,6 +1236,11 @@ package body Sem_Ch8 is
end if; end if;
Inherit_Renamed_Profile (New_S, Old_S); Inherit_Renamed_Profile (New_S, Old_S);
-- The prefix can be an arbitrary expression that yields a task
-- type, so it must be resolved.
Resolve (Prefix (Nam), Scope (Old_S));
end if; end if;
Set_Convention (New_S, Convention (Old_S)); Set_Convention (New_S, Convention (Old_S));
...@@ -1265,6 +1296,114 @@ package body Sem_Ch8 is ...@@ -1265,6 +1296,114 @@ package body Sem_Ch8 is
end if; end if;
end Analyze_Renamed_Family_Member; end Analyze_Renamed_Family_Member;
-----------------------------------------
-- Analyze_Renamed_Primitive_Operation --
-----------------------------------------
procedure Analyze_Renamed_Primitive_Operation
(N : Node_Id;
New_S : Entity_Id;
Is_Body : Boolean)
is
Old_S : Entity_Id;
function Conforms
(Subp : Entity_Id;
Ctyp : Conformance_Type) return Boolean;
-- Verify that the signatures of the renamed entity and the new entity
-- match. The first formal of the renamed entity is skipped because it
-- is the target object in any subsequent call.
function Conforms
(Subp : Entity_Id;
Ctyp : Conformance_Type) return Boolean
is
Old_F : Entity_Id;
New_F : Entity_Id;
begin
if Ekind (Subp) /= Ekind (New_S) then
return False;
end if;
Old_F := Next_Formal (First_Formal (Subp));
New_F := First_Formal (New_S);
while Present (Old_F) and then Present (New_F) loop
if not Conforming_Types (Etype (Old_F), Etype (New_F), Ctyp) then
return False;
end if;
if Ctyp >= Mode_Conformant
and then Ekind (Old_F) /= Ekind (New_F)
then
return False;
end if;
Next_Formal (New_F);
Next_Formal (Old_F);
end loop;
return True;
end Conforms;
begin
if not Is_Overloaded (Selector_Name (Name (N))) then
Old_S := Entity (Selector_Name (Name (N)));
if not Conforms (Old_S, Type_Conformant) then
Old_S := Any_Id;
end if;
else
-- Find the operation that matches the given signature
declare
It : Interp;
Ind : Interp_Index;
begin
Old_S := Any_Id;
Get_First_Interp (Selector_Name (Name (N)), Ind, It);
while Present (It.Nam) loop
if Conforms (It.Nam, Type_Conformant) then
Old_S := It.Nam;
end if;
Get_Next_Interp (Ind, It);
end loop;
end;
end if;
if Old_S = Any_Id then
Error_Msg_N (" no subprogram or entry matches specification", N);
else
if Is_Body then
if not Conforms (Old_S, Subtype_Conformant) then
Error_Msg_N ("subtype conformance error in renaming", N);
end if;
Generate_Reference (New_S, Defining_Entity (N), 'b');
Style.Check_Identifier (Defining_Entity (N), New_S);
else
-- Only mode conformance required for a renaming_as_declaration
if not Conforms (Old_S, Mode_Conformant) then
Error_Msg_N ("mode conformance error in renaming", N);
end if;
end if;
-- Inherit_Renamed_Profile (New_S, Old_S);
-- The prefix can be an arbitrary expression that yields an
-- object, so it must be resolved.
Resolve (Prefix (Name (N)));
end if;
end Analyze_Renamed_Primitive_Operation;
--------------------------------- ---------------------------------
-- Analyze_Subprogram_Renaming -- -- Analyze_Subprogram_Renaming --
--------------------------------- ---------------------------------
...@@ -1573,14 +1712,17 @@ package body Sem_Ch8 is ...@@ -1573,14 +1712,17 @@ package body Sem_Ch8 is
Rename_Spec := Find_Corresponding_Spec (N); Rename_Spec := Find_Corresponding_Spec (N);
-- Case of Renaming_As_Body
if Present (Rename_Spec) then if Present (Rename_Spec) then
-- Renaming_As_Body. Renaming declaration is the completion of -- Renaming declaration is the completion of the declaration of
-- the declaration of Rename_Spec. We will build an actual body -- Rename_Spec. We build an actual body for it at the freezing point.
-- for it at the freezing point.
Set_Corresponding_Spec (N, Rename_Spec); Set_Corresponding_Spec (N, Rename_Spec);
-- Deal with special case of Input and Output stream functions
if Nkind (Unit_Declaration_Node (Rename_Spec)) = if Nkind (Unit_Declaration_Node (Rename_Spec)) =
N_Abstract_Subprogram_Declaration N_Abstract_Subprogram_Declaration
then then
...@@ -1622,6 +1764,13 @@ package body Sem_Ch8 is ...@@ -1622,6 +1764,13 @@ package body Sem_Ch8 is
Check_Fully_Conformant (New_S, Rename_Spec); Check_Fully_Conformant (New_S, Rename_Spec);
Set_Public_Status (New_S); Set_Public_Status (New_S);
-- The specification does not introduce new formals, but only
-- repeats the formals of the original subprogram declaration.
-- For cross-reference purposes, and for refactoring tools, we
-- treat the formals of the renaming declaration as body formals.
Reference_Body_Formals (Rename_Spec, New_S);
-- Indicate that the entity in the declaration functions like the -- Indicate that the entity in the declaration functions like the
-- corresponding body, and is not a new entity. The body will be -- corresponding body, and is not a new entity. The body will be
-- constructed later at the freeze point, so indicate that the -- constructed later at the freeze point, so indicate that the
...@@ -1645,6 +1794,8 @@ package body Sem_Ch8 is ...@@ -1645,6 +1794,8 @@ package body Sem_Ch8 is
("subprogram& overrides inherited operation", N, Rename_Spec); ("subprogram& overrides inherited operation", N, Rename_Spec);
end if; end if;
-- Normal subprogram renaming (not renaming as body)
else else
Generate_Definition (New_S); Generate_Definition (New_S);
New_Overloaded_Entity (New_S); New_Overloaded_Entity (New_S);
...@@ -1671,12 +1822,57 @@ package body Sem_Ch8 is ...@@ -1671,12 +1822,57 @@ package body Sem_Ch8 is
elsif Nkind (Nam) = N_Selected_Component then elsif Nkind (Nam) = N_Selected_Component then
-- Renamed entity is an entry or protected subprogram. For those -- A prefix of the form A.B can designate an entry of task A, a
-- cases an explicit body is built (at the point of freezing of this -- protected operation of protected object A, or finally a primitive
-- entity) that contains a call to the renamed entity. -- operation of object A. In the later case, A is an object of some
-- tagged type, or an access type that denotes one such. To further
-- distinguish these cases, note that the scope of a task entry or
-- protected operation is type of the prefix.
-- The prefix could be an overloaded function call that returns both
-- kinds of operations. This overloading pathology is left to the
-- dedicated reader ???
declare
T : constant Entity_Id := Etype (Prefix (Nam));
begin
if Present (T)
and then
(Is_Tagged_Type (T)
or else
(Is_Access_Type (T)
and then
Is_Tagged_Type (Designated_Type (T))))
and then Scope (Entity (Selector_Name (Nam))) /= T
then
Analyze_Renamed_Primitive_Operation
(N, New_S, Present (Rename_Spec));
return;
else
-- Renamed entity is an entry or protected operation. For those
-- cases an explicit body is built (at the point of freezing of
-- this entity) that contains a call to the renamed entity.
-- This is not allowed for renaming as body if the renamed
-- spec is already frozen (see RM 8.5.4(5) for details).
if Present (Rename_Spec)
and then Is_Frozen (Rename_Spec)
then
Error_Msg_N
("renaming-as-body cannot rename entry as subprogram", N);
Error_Msg_NE
("\since & is already frozen (RM 8.5.4(5))",
N, Rename_Spec);
else
Analyze_Renamed_Entry (N, New_S, Present (Rename_Spec)); Analyze_Renamed_Entry (N, New_S, Present (Rename_Spec));
end if;
return; return;
end if;
end;
elsif Nkind (Nam) = N_Explicit_Dereference then elsif Nkind (Nam) = N_Explicit_Dereference then
...@@ -2760,8 +2956,8 @@ package body Sem_Ch8 is ...@@ -2760,8 +2956,8 @@ package body Sem_Ch8 is
Pop_Scope; Pop_Scope;
while not (Is_List_Member (Decl)) while not (Is_List_Member (Decl))
or else Nkind (Parent (Decl)) = N_Protected_Definition or else Nkind_In (Parent (Decl), N_Protected_Definition,
or else Nkind (Parent (Decl)) = N_Task_Definition N_Task_Definition)
loop loop
Decl := Parent (Decl); Decl := Parent (Decl);
end loop; end loop;
...@@ -3339,10 +3535,7 @@ package body Sem_Ch8 is ...@@ -3339,10 +3535,7 @@ package body Sem_Ch8 is
if Nkind (N) = N_Identifier if Nkind (N) = N_Identifier
and then Nkind (Parent (N)) = N_Case_Statement_Alternative and then Nkind (Parent (N)) = N_Case_Statement_Alternative
then then
Get_Name_String (Chars (N));
declare declare
Case_Str : constant String := Name_Buffer (1 .. Name_Len);
Case_Stm : constant Node_Id := Parent (Parent (N)); Case_Stm : constant Node_Id := Parent (Parent (N));
Case_Typ : constant Entity_Id := Etype (Expression (Case_Stm)); Case_Typ : constant Entity_Id := Etype (Expression (Case_Stm));
Case_Rtp : constant Entity_Id := Root_Type (Case_Typ); Case_Rtp : constant Entity_Id := Root_Type (Case_Typ);
...@@ -3359,9 +3552,7 @@ package body Sem_Ch8 is ...@@ -3359,9 +3552,7 @@ package body Sem_Ch8 is
Get_Name_String (Chars (Lit)); Get_Name_String (Chars (Lit));
if Chars (Lit) /= Chars (N) if Chars (Lit) /= Chars (N)
and then Is_Bad_Spelling_Of and then Is_Bad_Spelling_Of (Chars (N), Chars (Lit)) then
(Case_Str, Name_Buffer (1 .. Name_Len))
then
Error_Msg_Node_2 := Lit; Error_Msg_Node_2 := Lit;
Error_Msg_N Error_Msg_N
("& is undefined, assume misspelling of &", N); ("& is undefined, assume misspelling of &", N);
...@@ -3445,8 +3636,6 @@ package body Sem_Ch8 is ...@@ -3445,8 +3636,6 @@ package body Sem_Ch8 is
-- Now check for possible misspellings -- Now check for possible misspellings
Get_Name_String (Chars (N));
declare declare
E : Entity_Id; E : Entity_Id;
Ematch : Entity_Id := Empty; Ematch : Entity_Id := Empty;
...@@ -3455,23 +3644,16 @@ package body Sem_Ch8 is ...@@ -3455,23 +3644,16 @@ package body Sem_Ch8 is
Name_Id (Nat (First_Name_Id) + Name_Id (Nat (First_Name_Id) +
Name_Entries_Count - 1); Name_Entries_Count - 1);
S : constant String (1 .. Name_Len) :=
Name_Buffer (1 .. Name_Len);
begin begin
for N in First_Name_Id .. Last_Name_Id loop for Nam in First_Name_Id .. Last_Name_Id loop
E := Get_Name_Entity_Id (N); E := Get_Name_Entity_Id (Nam);
if Present (E) if Present (E)
and then (Is_Immediately_Visible (E) and then (Is_Immediately_Visible (E)
or else or else
Is_Potentially_Use_Visible (E)) Is_Potentially_Use_Visible (E))
then then
Get_Name_String (N); if Is_Bad_Spelling_Of (Chars (N), Nam) then
if Is_Bad_Spelling_Of
(S, Name_Buffer (1 .. Name_Len))
then
Ematch := E; Ematch := E;
exit; exit;
end if; end if;
...@@ -3812,6 +3994,18 @@ package body Sem_Ch8 is ...@@ -3812,6 +3994,18 @@ package body Sem_Ch8 is
<<Found>> begin <<Found>> begin
-- When distribution features are available (Get_PCS_Name /=
-- Name_No_DSA), a remote access-to-subprogram type is converted
-- into a record type holding whatever information is needed to
-- perform a remote call on an RCI suprogram. In that case we
-- rewrite any occurrence of the RAS type into the equivalent record
-- type here. 'Access attribute references and RAS dereferences are
-- then implemented using specific TSSs. However when distribution is
-- not available (case of Get_PCS_Name = Name_No_DSA), we bypass the
-- generation of these TSSs, and we must keep the RAS type in its
-- original access-to-subprogram form (since all calls through a
-- value of such type will be local anyway in the absence of a PCS).
if Comes_From_Source (N) if Comes_From_Source (N)
and then Is_Remote_Access_To_Subprogram_Type (E) and then Is_Remote_Access_To_Subprogram_Type (E)
and then Expander_Active and then Expander_Active
...@@ -3875,17 +4069,28 @@ package body Sem_Ch8 is ...@@ -3875,17 +4069,28 @@ package body Sem_Ch8 is
-- to the discriminant in the initialization procedure. -- to the discriminant in the initialization procedure.
else else
-- Entity is unambiguous, indicate that it is referenced here. One -- Entity is unambiguous, indicate that it is referenced here
-- slightly odd case is that we do not want to set the Referenced
-- flag if the entity is a label, and the identifier is the label -- For a renaming of an object, always generate simple reference,
-- in the source, since this is not a reference from the point of -- we don't try to keep track of assignments in this case.
-- view of the user
if Is_Object (E) and then Present (Renamed_Object (E)) then
Generate_Reference (E, N);
-- One odd case is that we do not want to set the Referenced flag
-- if the entity is a label, and the identifier is the label in
-- the source, since this is not a reference from the point of
-- view of the user.
if Nkind (Parent (N)) = N_Label then elsif Nkind (Parent (N)) = N_Label then
declare declare
R : constant Boolean := Referenced (E); R : constant Boolean := Referenced (E);
begin begin
if not Is_Actual_Parameter then -- Generate reference unless this is an actual parameter
-- (see comment below)
if Is_Actual_Parameter then
Generate_Reference (E, N); Generate_Reference (E, N);
Set_Referenced (E, R); Set_Referenced (E, R);
end if; end if;
...@@ -3938,8 +4143,8 @@ package body Sem_Ch8 is ...@@ -3938,8 +4143,8 @@ package body Sem_Ch8 is
begin begin
P := Parent (N); P := Parent (N);
while Present (P) while Present (P)
and then Nkind (P) /= N_Parameter_Specification and then not Nkind_In (P, N_Parameter_Specification,
and then Nkind (P) /= N_Component_Declaration N_Component_Declaration)
loop loop
P := Parent (P); P := Parent (P);
end loop; end loop;
...@@ -4225,16 +4430,8 @@ package body Sem_Ch8 is ...@@ -4225,16 +4430,8 @@ package body Sem_Ch8 is
-- Check for misspelling of some entity in prefix -- Check for misspelling of some entity in prefix
Id := First_Entity (P_Name); Id := First_Entity (P_Name);
Get_Name_String (Chars (Selector));
declare
S : constant String (1 .. Name_Len) :=
Name_Buffer (1 .. Name_Len);
begin
while Present (Id) loop while Present (Id) loop
Get_Name_String (Chars (Id)); if Is_Bad_Spelling_Of (Chars (Id), Chars (Selector))
if Is_Bad_Spelling_Of
(Name_Buffer (1 .. Name_Len), S)
and then not Is_Internal_Name (Chars (Id)) and then not Is_Internal_Name (Chars (Id))
then then
Error_Msg_NE Error_Msg_NE
...@@ -4244,7 +4441,6 @@ package body Sem_Ch8 is ...@@ -4244,7 +4441,6 @@ package body Sem_Ch8 is
Next_Entity (Id); Next_Entity (Id);
end loop; end loop;
end;
-- Specialize the message if this may be an instantiation -- Specialize the message if this may be an instantiation
-- of a child unit that was not mentioned in the context. -- of a child unit that was not mentioned in the context.
...@@ -6179,9 +6375,11 @@ package body Sem_Ch8 is ...@@ -6179,9 +6375,11 @@ package body Sem_Ch8 is
The_Unit := Unit (Cunit (Current_Sem_Unit)); The_Unit := Unit (Cunit (Current_Sem_Unit));
if No (With_Sys) if No (With_Sys)
and then (Nkind (The_Unit) = N_Package_Body and then
(Nkind (The_Unit) = N_Package_Body
or else (Nkind (The_Unit) = N_Subprogram_Body or else (Nkind (The_Unit) = N_Subprogram_Body
and then not Acts_As_Spec (Cunit (Current_Sem_Unit)))) and then
not Acts_As_Spec (Cunit (Current_Sem_Unit))))
then then
With_Sys := Find_System (Library_Unit (Cunit (Current_Sem_Unit))); With_Sys := Find_System (Library_Unit (Cunit (Current_Sem_Unit)));
end if; end if;
...@@ -6193,7 +6391,6 @@ package body Sem_Ch8 is ...@@ -6193,7 +6391,6 @@ package body Sem_Ch8 is
-- context as well (Current_Sem_Unit is the parent unit); -- context as well (Current_Sem_Unit is the parent unit);
The_Unit := Parent (N); The_Unit := Parent (N);
while Nkind (The_Unit) /= N_Compilation_Unit loop while Nkind (The_Unit) /= N_Compilation_Unit loop
The_Unit := Parent (The_Unit); The_Unit := Parent (The_Unit);
end loop; end loop;
...@@ -6694,7 +6891,14 @@ package body Sem_Ch8 is ...@@ -6694,7 +6891,14 @@ package body Sem_Ch8 is
if In_Open_Scopes (Scope (T)) then if In_Open_Scopes (Scope (T)) then
null; null;
elsif From_With_Type (T) then -- A limited view cannot appear in a use_type clause. However, an
-- access type whose designated type is limited has the flag but
-- is not itself a limited view unless we only have a limited view
-- of its enclosing package.
elsif From_With_Type (T)
and then From_With_Type (Scope (T))
then
Error_Msg_N Error_Msg_N
("incomplete type from limited view " ("incomplete type from limited view "
& "cannot appear in use clause", Id); & "cannot appear in use clause", Id);
......
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