aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_ch12.adb
diff options
context:
space:
mode:
authorHristian Kirtchev <kirtchev@adacore.com>2016-04-20 10:19:57 +0000
committerArnaud Charlet <charlet@gcc.gnu.org>2016-04-20 12:19:57 +0200
commit5c63aafa2e9b9854ee03481d33b8cc009c818e4e (patch)
treefbc908f1eaee497bacf39f846a2908c0f26aa8eb /gcc/ada/sem_ch12.adb
parent7e22a38c2f5f173ac220cd9ec70b55ce08243797 (diff)
downloadgcc-5c63aafa2e9b9854ee03481d33b8cc009c818e4e.zip
gcc-5c63aafa2e9b9854ee03481d33b8cc009c818e4e.tar.gz
gcc-5c63aafa2e9b9854ee03481d33b8cc009c818e4e.tar.bz2
sem_ch12.adb (Qualify_Universal_Operands): New routine.
2016-04-20 Hristian Kirtchev <kirtchev@adacore.com> * sem_ch12.adb (Qualify_Universal_Operands): New routine. (Save_References_In_Operator): Add explicit qualifications in the generic template for all operands of universal type. * sem_type.adb (Disambiguate): Update the call to Matches. (Matches): Reimplemented. * sem_util.ads, sem_util.adb (Yields_Universal_Type): New routine. From-SVN: r235254
Diffstat (limited to 'gcc/ada/sem_ch12.adb')
-rw-r--r--gcc/ada/sem_ch12.adb129
1 files changed, 127 insertions, 2 deletions
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index fe867f3..bd7a6a4 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -13848,6 +13848,19 @@ package body Sem_Ch12 is
-- global because it is used to denote a specific compilation unit at
-- the time the instantiations will be analyzed.
+ procedure Qualify_Universal_Operands
+ (Op : Node_Id;
+ Func_Call : Node_Id);
+ -- Op denotes a binary or unary operator in generic template Templ. Node
+ -- Func_Call is the function call alternative of the operator within the
+ -- the analyzed copy of the template. Change each operand which yields a
+ -- universal type by wrapping it into a qualified expression
+ --
+ -- Actual_Typ'(Operand)
+ --
+ -- where Actual_Typ is the type of corresponding actual parameter of
+ -- Operand in Func_Call.
+
procedure Reset_Entity (N : Node_Id);
-- Save semantic information on global entity so that it is not resolved
-- again at instantiation time.
@@ -13938,6 +13951,109 @@ package body Sem_Ch12 is
end if;
end Is_Global;
+ --------------------------------
+ -- Qualify_Universal_Operands --
+ --------------------------------
+
+ procedure Qualify_Universal_Operands
+ (Op : Node_Id;
+ Func_Call : Node_Id)
+ is
+ procedure Qualify_Operand (Opnd : Node_Id; Actual : Node_Id);
+ -- Rewrite operand Opnd as a qualified expression of the form
+ --
+ -- Actual_Typ'(Opnd)
+ --
+ -- where Actual is the corresponding actual parameter of Opnd in
+ -- function call Func_Call.
+
+ function Qualify_Type
+ (Loc : Source_Ptr;
+ Typ : Entity_Id) return Node_Id;
+ -- Qualify type Typ by creating a selected component of the form
+ --
+ -- Scope_Of_Typ.Typ
+
+ ---------------------
+ -- Qualify_Operand --
+ ---------------------
+
+ procedure Qualify_Operand (Opnd : Node_Id; Actual : Node_Id) is
+ Loc : constant Source_Ptr := Sloc (Opnd);
+ Typ : constant Entity_Id := Etype (Actual);
+ Mark : Node_Id;
+
+ begin
+ -- Qualify the operand when it is of a universal type. Note that
+ -- the template is unanalyzed and it is not possible to directly
+ -- query the type. This transformation is not done when the type
+ -- of the actual is internally generated because the type will be
+ -- regenerated in the instance.
+
+ if Yields_Universal_Type (Opnd)
+ and then Comes_From_Source (Typ)
+ and then not Is_Hidden (Typ)
+ then
+ -- The type of the actual may be a global reference. Save this
+ -- information by creating a reference to it.
+
+ if Is_Global (Typ) then
+ Mark := New_Occurrence_Of (Typ, Loc);
+
+ -- Otherwise rely on resolution to find the proper type within
+ -- the instance.
+
+ else
+ Mark := Qualify_Type (Loc, Typ);
+ end if;
+
+ Rewrite (Opnd,
+ Make_Qualified_Expression (Loc,
+ Subtype_Mark => Mark,
+ Expression => Relocate_Node (Opnd)));
+ end if;
+ end Qualify_Operand;
+
+ ------------------
+ -- Qualify_Type --
+ ------------------
+
+ function Qualify_Type
+ (Loc : Source_Ptr;
+ Typ : Entity_Id) return Node_Id
+ is
+ Scop : constant Entity_Id := Scope (Typ);
+ Result : Node_Id;
+
+ begin
+ Result := Make_Identifier (Loc, Chars (Typ));
+
+ if Present (Scop) and then Scop /= Standard_Standard then
+ Result :=
+ Make_Selected_Component (Loc,
+ Prefix => Make_Identifier (Loc, Chars (Scop)),
+ Selector_Name => Result);
+ end if;
+
+ return Result;
+ end Qualify_Type;
+
+ -- Local variables
+
+ Actuals : constant List_Id := Parameter_Associations (Func_Call);
+
+ -- Start of processing for Qualify_Universal_Operands
+
+ begin
+ if Nkind (Op) in N_Binary_Op then
+ Qualify_Operand (Left_Opnd (Op), First (Actuals));
+ Qualify_Operand (Right_Opnd (Op), Next (First (Actuals)));
+
+ elsif Nkind (Op) in N_Unary_Op then
+ Qualify_Operand (Right_Opnd (Op), First (Actuals));
+ end if;
+ end Qualify_Universal_Operands;
+
------------------
-- Reset_Entity --
------------------
@@ -14716,7 +14832,8 @@ package body Sem_Ch12 is
Reset_Entity (N);
-- The analysis of the generic copy transformed the operator into
- -- some other construct. Propagate the changes to the template.
+ -- some other construct. Propagate the changes to the template if
+ -- applicable.
else
N2 := Get_Associated_Node (N);
@@ -14724,13 +14841,21 @@ package body Sem_Ch12 is
-- The operator resoved to a function call
if Nkind (N2) = N_Function_Call then
+
+ -- Add explicit qualifications in the generic template for
+ -- all operands of universal type. This aids resolution by
+ -- preserving the actual type of a literal or an attribute
+ -- that yields a universal result.
+
+ Qualify_Universal_Operands (N, N2);
+
E := Entity (Name (N2));
if Present (E) and then Is_Global (E) then
Set_Etype (N, Etype (N2));
else
Set_Associated_Node (N, Empty);
- Set_Etype (N, Empty);
+ Set_Etype (N, Empty);
end if;
-- The operator was folded into a literal