aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorEd Schonberg <schonberg@adacore.com>2007-04-06 11:26:20 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2007-04-06 11:26:20 +0200
commitaab883ecd1e8d05346815ae041e7c9c9e1cb7431 (patch)
treee9bd15814fc83fc88fc867340d4292acea3c954e /gcc/ada
parentda931119f4caeba05e524717a2ee3492aecb5bb0 (diff)
downloadgcc-aab883ecd1e8d05346815ae041e7c9c9e1cb7431.zip
gcc-aab883ecd1e8d05346815ae041e7c9c9e1cb7431.tar.gz
gcc-aab883ecd1e8d05346815ae041e7c9c9e1cb7431.tar.bz2
sem_ch4.adb (Try_Primitive_Operation): The call is legal if the prefix type is a discriminated subtype of the type of...
2007-04-06 Ed Schonberg <schonberg@adacore.com> Bob Duff <duff@adacore.com> Gary Dismukes <dismukes@adacore.com> * sem_ch4.adb (Try_Primitive_Operation): The call is legal if the prefix type is a discriminated subtype of the type of the formal. (Analyze_Allocator): Collect all coextensions regardless of the context. Whether they can be allocated statically is determined in exp_ch4. (Analyze_Selected_Component): If the prefix is a limited view and the non-limited view is available, use the non-limited one. (Operator_Check): For "X'Access = Y'Access" (which is ambiguous, and therefore illegal), suggest a qualified expression rather than a type conversion, because a type conversion would be illegal in this context. (Anayze_Allocator): Trace recursively all nested allocators so that all coextensions are on the corresponding list for the root. Do no mark coextensions if the root allocator is within a declaration for a stack- allocated object, because the access discriminants will be allocated on the stack as well. (Analyze_Call): Remove restriction on calls to limited functions for the cases of generic actuals for formal objects, defaults for formal objects and defaults for record components. (Analyze_Allocator): Before analysis, chain coextensions on the proper element list. Their expansion is delayed until the enclosing allocator is processed and its finalization list constructed. (Try_Primitive_Operation): If the prefix is a concurrent type, looks for an operation with the given name among the primitive operations of the corresponding record type. (Analyze_Selected_Component): If the prefix is a task type that implements an interface, and there is no entry with the given name, check whether there is another primitive operation (e.g. a function) with that name. (Try_Object_Operation, Analyze_One_Call, Try_Indexed_Call): Handle properly the indexing of a function call written in prefix form, where the function returns an array type, and all parameters of the function except the first have defaults. (Analyze_Equality_Op): If this is a call to an implicit inequality, keep the original operands, rather than relocating them, for efficiency and to work properly when an operand is overloaded. (Analyze_Allocator,Operator_Check,Remove_Abstract_Operations): Split Is_Abstract flag into Is_Abstract_Subprogram and Is_Abstract_Type. (Analyze_Selected_Component): If the prefix is a private extension, only scan the visible components, not those of the full view. (Try_Primitive_Operation): If the operation is a procedure, collect all possible interpretations, as for a function, because in the presence of classwide parameters several primitive operations of the type can match the given arguments. From-SVN: r123594
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/sem_ch4.adb252
1 files changed, 184 insertions, 68 deletions
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index 6d8e81e..14f7c10 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -234,25 +234,28 @@ package body Sem_Ch4 is
-- operation is not a candidate interpretation.
function Try_Indexed_Call
- (N : Node_Id;
- Nam : Entity_Id;
- Typ : Entity_Id) return Boolean;
- -- If a function has defaults for all its actuals, a call to it may
- -- in fact be an indexing on the result of the call. Try_Indexed_Call
- -- attempts the interpretation as an indexing, prior to analysis as
- -- a call. If both are possible, the node is overloaded with both
- -- interpretations (same symbol but two different types).
+ (N : Node_Id;
+ Nam : Entity_Id;
+ Typ : Entity_Id;
+ Skip_First : Boolean) return Boolean;
+ -- If a function has defaults for all its actuals, a call to it may in fact
+ -- be an indexing on the result of the call. Try_Indexed_Call attempts the
+ -- interpretation as an indexing, prior to analysis as a call. If both are
+ -- possible, the node is overloaded with both interpretations (same symbol
+ -- but two different types). If the call is written in prefix form, the
+ -- prefix becomes the first parameter in the call, and only the remaining
+ -- actuals must be checked for the presence of defaults.
function Try_Indirect_Call
(N : Node_Id;
Nam : Entity_Id;
Typ : Entity_Id) return Boolean;
- -- Similarly, a function F that needs no actuals can return an access
- -- to a subprogram, and the call F (X) interpreted as F.all (X). In
- -- this case the call may be overloaded with both interpretations.
+ -- Similarly, a function F that needs no actuals can return an access to a
+ -- subprogram, and the call F (X) interpreted as F.all (X). In this case
+ -- the call may be overloaded with both interpretations.
function Try_Object_Operation (N : Node_Id) return Boolean;
- -- Ada 2005 (AI-252): Give support to the object operation notation
+ -- Ada 2005 (AI-252): Support the object.operation notation
------------------------
-- Ambiguous_Operands --
@@ -343,10 +346,48 @@ package body Sem_Ch4 is
Acc_Type : Entity_Id;
Type_Id : Entity_Id;
+ function Mark_Allocator (Nod : Node_Id) return Traverse_Result;
+ -- Ada 2005 AI-162: Traverse the expression for an allocator, to locate
+ -- inner allocators that may specify access discriminants. Such access
+ -- discriminants are coextensions of the enclosing objects. They should
+ -- be allocated from the same storage pool as the enclosing object, and
+ -- deallocated at the same time as the enclosing object. They are
+ -- linked to the enclosing allocator to simplify this sharing.
+ -- On the other hand, access discriminants for stack-allocated objects
+ -- are themselves allocated statically, and do not carry the flag.
+
+ --------------------
+ -- Mark_Allocator --
+ --------------------
+
+ function Mark_Allocator (Nod : Node_Id) return Traverse_Result is
+ begin
+ if Nkind (Nod) = N_Allocator
+ and then Nkind (Parent (Nod)) = N_Index_Or_Discriminant_Constraint
+ then
+ Set_Is_Coextension (Nod);
+
+ if No (Coextensions (N)) then
+ Set_Coextensions (N, New_Elmt_List);
+ end if;
+
+ Append_Elmt (Nod, Coextensions (N));
+ end if;
+
+ return OK;
+ end Mark_Allocator;
+
+ procedure Mark_Coextensions is new Traverse_Proc (Mark_Allocator);
+
+ -- Start of processing for Analyze_Allocator
+
begin
Check_Restriction (No_Allocators, N);
+ Set_Coextensions (N, No_Elist);
+ Mark_Coextensions (E);
if Nkind (E) = N_Qualified_Expression then
+
Acc_Type := Create_Itype (E_Allocator_Type, N);
Set_Etype (Acc_Type, Acc_Type);
Init_Size_Align (Acc_Type);
@@ -383,7 +424,7 @@ package body Sem_Ch4 is
Set_Etype (E, Type_Id);
- -- Case where no qualified expression is present
+ -- Case where allocator has a subtype indication
else
declare
@@ -507,7 +548,7 @@ package body Sem_Ch4 is
end;
end if;
- if Is_Abstract (Type_Id) then
+ if Is_Abstract_Type (Type_Id) then
Error_Msg_N ("cannot allocate abstract object", E);
end if;
@@ -904,8 +945,8 @@ package body Sem_Ch4 is
elsif not Is_Overloaded (N)
and then Is_Entity_Name (Nam)
then
- -- Resolution yields a single interpretation. Verify that
- -- is has the proper capitalization.
+ -- Resolution yields a single interpretation. Verify that the
+ -- reference has capitalization consistent with the declaration.
Set_Entity_With_Style_Check (Nam, Entity (Nam));
Generate_Reference (Entity (Nam), Nam);
@@ -918,21 +959,17 @@ package body Sem_Ch4 is
End_Interp_List;
end if;
- -- Check for not-yet-implemented cases of AI-318.
- -- We only need to check for inherently limited types,
- -- because other limited types will be returned by copy,
- -- which works just fine.
+ -- Check for not-yet-implemented cases of AI-318. We only need to check
+ -- for inherently limited types, because other limited types will be
+ -- returned by copy, which works just fine.
if Ada_Version >= Ada_05
and then not Debug_Flag_Dot_L
and then Is_Inherently_Limited_Type (Etype (N))
and then (Nkind (Parent (N)) = N_Selected_Component
- or else Nkind (Parent (N)) = N_Indexed_Component
- or else Nkind (Parent (N)) = N_Slice
- or else Nkind (Parent (N)) = N_Attribute_Reference
- or else Nkind (Parent (N)) = N_Component_Declaration
- or else Nkind (Parent (N)) = N_Formal_Object_Declaration
- or else Nkind (Parent (N)) = N_Generic_Association)
+ or else Nkind (Parent (N)) = N_Indexed_Component
+ or else Nkind (Parent (N)) = N_Slice
+ or else Nkind (Parent (N)) = N_Attribute_Reference)
then
Error_Msg_N ("(Ada 2005) limited function call in this context" &
" is not yet implemented", N);
@@ -1183,8 +1220,8 @@ package body Sem_Ch4 is
Make_Op_Not (Loc,
Right_Opnd =>
Make_Op_Eq (Loc,
- Left_Opnd => Relocate_Node (Left_Opnd (N)),
- Right_Opnd => Relocate_Node (Right_Opnd (N)))));
+ Left_Opnd => Left_Opnd (N),
+ Right_Opnd => Right_Opnd (N))));
Set_Entity (Right_Opnd (N), Op_Id);
Analyze (N);
@@ -1678,7 +1715,7 @@ package body Sem_Ch4 is
then
U_N := Entity (P);
- if Ekind (U_N) in Type_Kind then
+ if Is_Type (U_N) then
-- Reformat node as a type conversion
@@ -1947,6 +1984,18 @@ package body Sem_Ch4 is
is
Actuals : constant List_Id := Parameter_Associations (N);
Prev_T : constant Entity_Id := Etype (N);
+ Must_Skip : constant Boolean := Skip_First
+ or else Nkind (Original_Node (N)) = N_Selected_Component
+ or else
+ (Nkind (Original_Node (N)) = N_Indexed_Component
+ and then Nkind (Prefix (Original_Node (N)))
+ = N_Selected_Component);
+ -- The first formal must be omitted from the match when trying to find
+ -- a primitive operation that is a possible interpretation, and also
+ -- after the call has been rewritten, because the corresponding actual
+ -- is already known to be compatible, and because this may be an
+ -- indexing of a call with default parameters.
+
Formal : Entity_Id;
Actual : Node_Id;
Is_Indexed : Boolean := False;
@@ -2000,18 +2049,26 @@ package body Sem_Ch4 is
-- If the subprogram has no formals, or if all the formals have
-- defaults, and the return type is an array type, the node may
-- denote an indexing of the result of a parameterless call.
+ -- In Ada 2005, the subprogram may have one non-defaulted formal,
+ -- and the call may have been written in prefix notation, so that
+ -- the rebuilt parameter list has more than one actual.
- if Needs_No_Actuals (Nam)
- and then Present (Actuals)
+ if Present (Actuals)
+ and then
+ (Needs_No_Actuals (Nam)
+ or else
+ (Needs_One_Actual (Nam)
+ and then Present (Next_Actual (First (Actuals)))))
then
if Is_Array_Type (Subp_Type) then
- Is_Indexed := Try_Indexed_Call (N, Nam, Subp_Type);
+ Is_Indexed := Try_Indexed_Call (N, Nam, Subp_Type, Must_Skip);
elsif Is_Access_Type (Subp_Type)
and then Is_Array_Type (Designated_Type (Subp_Type))
then
Is_Indexed :=
- Try_Indexed_Call (N, Nam, Designated_Type (Subp_Type));
+ Try_Indexed_Call
+ (N, Nam, Designated_Type (Subp_Type), Must_Skip);
-- The prefix can also be a parameterless function that returns an
-- access to subprogram. in which case this is an indirect call.
@@ -2131,7 +2188,7 @@ package body Sem_Ch4 is
-- skip first actual, which may be rewritten later as an
-- explicit dereference.
- if Skip_First then
+ if Must_Skip then
Next_Actual (Actual);
Next_Formal (Formal);
end if;
@@ -2618,16 +2675,33 @@ package body Sem_Ch4 is
Prefix_Type := Designated_Type (Prefix_Type);
- -- (Ada 2005): if the prefix is the limited view of a type, and
- -- the context already includes the full view, use the full view
- -- in what follows, either to retrieve a component of to find
- -- a primitive operation.
+ end if;
- if Is_Incomplete_Type (Prefix_Type)
- and then From_With_Type (Prefix_Type)
- and then Present (Non_Limited_View (Prefix_Type))
- then
- Prefix_Type := Non_Limited_View (Prefix_Type);
+ -- (Ada 2005): if the prefix is the limited view of a type, and
+ -- the context already includes the full view, use the full view
+ -- in what follows, either to retrieve a component of to find
+ -- a primitive operation. If the prefix is an explicit dereference,
+ -- set the type of the prefix to reflect this transformation.
+
+ if Is_Incomplete_Type (Prefix_Type)
+ and then From_With_Type (Prefix_Type)
+ and then Present (Non_Limited_View (Prefix_Type))
+ then
+ Prefix_Type := Non_Limited_View (Prefix_Type);
+
+ if Nkind (N) = N_Explicit_Dereference then
+ Set_Etype (Prefix (N), Prefix_Type);
+ end if;
+
+ elsif Ekind (Prefix_Type) = E_Class_Wide_Type
+ and then From_With_Type (Prefix_Type)
+ and then Present (Non_Limited_View (Etype (Prefix_Type)))
+ then
+ Prefix_Type :=
+ Class_Wide_Type (Non_Limited_View (Etype (Prefix_Type)));
+
+ if Nkind (N) = N_Explicit_Dereference then
+ Set_Etype (Prefix (N), Prefix_Type);
end if;
end if;
@@ -2804,6 +2878,13 @@ package body Sem_Ch4 is
return;
end if;
+ -- If the prefix is a private extension, check only the visible
+ -- components of the partial view.
+
+ if Ekind (Prefix_Type) = E_Record_Type_With_Private then
+ exit when Comp = Last_Entity (Prefix_Type);
+ end if;
+
Next_Entity (Comp);
end loop;
@@ -2822,7 +2903,6 @@ package body Sem_Ch4 is
end if;
elsif Is_Private_Type (Prefix_Type) then
-
-- Allow access only to discriminants of the type. If the type has
-- no full view, gigi uses the parent type for the components, so we
-- do the same here.
@@ -2848,6 +2928,15 @@ package body Sem_Ch4 is
Set_Original_Discriminant (Sel, Comp);
end if;
+ -- Before declararing an error, check whether this is tagged
+ -- private type and a call to a primitive operation.
+
+ elsif Ada_Version >= Ada_05
+ and then Is_Tagged_Type (Prefix_Type)
+ and then Try_Object_Operation (N)
+ then
+ return;
+
else
Error_Msg_NE
("invisible selector for }",
@@ -2915,6 +3004,18 @@ package body Sem_Ch4 is
Comp = First_Private_Entity (Base_Type (Prefix_Type));
end loop;
+ -- If there is no visible entry with the given name, and the task
+ -- implements an interface, check whether there is some other
+ -- primitive operation with that name.
+
+ if Etype (N) = Any_Type
+ and then Ada_Version >= Ada_05
+ and then Is_Tagged_Type (Prefix_Type)
+ and then Try_Object_Operation (N)
+ then
+ return;
+ end if;
+
Set_Is_Overloaded (N, Is_Overloaded (Sel));
else
@@ -4528,7 +4629,7 @@ package body Sem_Ch4 is
Error_Msg_N
("two access attributes cannot be compared directly", N);
Error_Msg_N
- ("\they must be converted to an explicit type for comparison",
+ ("\use qualified expression for one of the operands",
N);
return;
@@ -4589,7 +4690,7 @@ package body Sem_Ch4 is
then
if not Is_Immediately_Visible (Op_Id)
and then not In_Use (Scope (Op_Id))
- and then not Is_Abstract (Op_Id)
+ and then not Is_Abstract_Subprogram (Op_Id)
and then not Is_Hidden (Op_Id)
and then Ekind (Scope (Op_Id)) = E_Package
and then
@@ -4712,8 +4813,8 @@ package body Sem_Ch4 is
Get_First_Interp (N, I, It);
while Present (It.Nam) loop
- if not Is_Type (It.Nam)
- and then Is_Abstract (It.Nam)
+ if Is_Overloadable (It.Nam)
+ and then Is_Abstract_Subprogram (It.Nam)
and then not Is_Dispatching_Operation (It.Nam)
then
Abstract_Op := It.Nam;
@@ -4932,9 +5033,10 @@ package body Sem_Ch4 is
----------------------
function Try_Indexed_Call
- (N : Node_Id;
- Nam : Entity_Id;
- Typ : Entity_Id) return Boolean
+ (N : Node_Id;
+ Nam : Entity_Id;
+ Typ : Entity_Id;
+ Skip_First : Boolean) return Boolean
is
Actuals : constant List_Id := Parameter_Associations (N);
Actual : Node_Id;
@@ -4942,6 +5044,14 @@ package body Sem_Ch4 is
begin
Actual := First (Actuals);
+
+ -- If the call was originally written in prefix form, skip the first
+ -- actual, which is obviously not defaulted.
+
+ if Skip_First then
+ Next (Actual);
+ end if;
+
Index := First_Index (Typ);
while Present (Actual) and then Present (Index) loop
@@ -5085,6 +5195,10 @@ package body Sem_Ch4 is
Rewrite (First_Actual, Obj);
end if;
+ if Is_Overloaded (Call_Node) then
+ Save_Interps (Call_Node, Node_To_Replace);
+ end if;
+
Rewrite (Node_To_Replace, Call_Node);
Analyze (Node_To_Replace);
end Complete_Object_Operation;
@@ -5290,9 +5404,10 @@ package body Sem_Ch4 is
Typ : constant Entity_Id := Etype (First_Formal (Op));
begin
- -- Simple case
+ -- Simple case. Object may be a subtype of the tagged type.
- return Base_Type (Obj_Type) = Typ
+ return Obj_Type = Typ
+ or else Base_Type (Obj_Type) = Typ
-- Prefix can be dereferenced
@@ -5314,8 +5429,17 @@ package body Sem_Ch4 is
-- Look for subprograms in the list of primitive operations
-- The name must be identical, and the kind of call indicates the
-- expected kind of operation (function or procedure).
+ -- If the type is a (tagged) synchronized type, the primitive ops
+ -- are attached to the corresponding record type.
+
+ if Is_Concurrent_Type (Obj_Type) then
+ Elmt :=
+ First_Elmt
+ (Primitive_Operations (Corresponding_Record_Type (Obj_Type)));
+ else
+ Elmt := First_Elmt (Primitive_Operations (Obj_Type));
+ end if;
- Elmt := First_Elmt (Primitive_Operations (Obj_Type));
while Present (Elmt) loop
Prim_Op := Node (Elmt);
@@ -5355,24 +5479,16 @@ package body Sem_Ch4 is
Success => Success,
Skip_First => True);
- if Success then
+ if Success
+ or else Needs_One_Actual (Prim_Op)
+ then
Op_Exists := True;
-
- -- If the operation is a procedure call, there can only
- -- be one candidate and we found it. If it is a function
- -- we must collect all interpretations, because there
- -- may be several primitive operations that differ only
- -- in the return type.
-
- if Nkind (Call_Node) = N_Procedure_Call_Statement then
- exit;
- end if;
end if;
- elsif Ekind (Prim_Op) = E_Function then
+ else
- -- Collect remaining function interpretations, to be
- -- resolved from context.
+ -- More than one interpretation, collect for subsequent
+ -- disambiguation.
Add_One_Interp (Prim_Op_Ref, Prim_Op, Etype (Prim_Op));
end if;