diff mbox

[Ada] Handling of function calls to predefined operators in ASIS

Message ID 20141120110101.GA32190@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Nov. 20, 2014, 11:01 a.m. UTC
An operator that is called in functional notation is rewritten as an operator
so that its operands can be properly resolved. ASIS needs the semantic info
to be available on the original node, so in ASIS mode the resolved operands
are linked back to the original call. This patch takes into account that the
call may have had named associations, using the standard operator arguments
Left and Right.

Tested on x86_64-pc-linux-gnu, committed on trunk

2014-11-20  Ed Schonberg  <schonberg@adacore.com>

	* sem_res.adb (Make_Call_Into_Operator): In ASIS mode, propagate
	back the resolved operands to the original call node, taking
	into account that the original call may have named associations.
diff mbox

Patch

Index: sem_res.adb
===================================================================
--- sem_res.adb	(revision 217828)
+++ sem_res.adb	(working copy)
@@ -1793,16 +1793,62 @@ 
         and then Nkind (N) in N_Op
         and then Nkind (Original_Node (N)) = N_Function_Call
       then
-         if Is_Binary then
-            Rewrite (First (Parameter_Associations (Original_Node (N))),
-               Relocate_Node (Left_Opnd (N)));
-            Rewrite (Next (First (Parameter_Associations (Original_Node (N)))),
-               Relocate_Node (Right_Opnd (N)));
-         else
-            Rewrite (First (Parameter_Associations (Original_Node (N))),
-               Relocate_Node (Right_Opnd (N)));
-         end if;
+         declare
+            L : constant Node_Id := Left_Opnd  (N);
+            R : constant Node_Id := Right_Opnd (N);
 
+            Old_First : constant Node_Id :=
+                          First (Parameter_Associations (Original_Node (N)));
+            Old_Sec   : Node_Id;
+
+         begin
+            if Is_Binary then
+               Old_Sec   := Next (Old_First);
+
+               --  If the original call has named associations, replace the
+               --  explicit actual parameter in the association with the proper
+               --  resolved operand.
+
+               if Nkind (Old_First) = N_Parameter_Association then
+                  if Chars (Selector_Name (Old_First)) =
+                     Chars (First_Entity (Op_Id))
+                  then
+                     Rewrite (Explicit_Actual_Parameter (Old_First),
+                       Relocate_Node (L));
+                  else
+                     Rewrite (Explicit_Actual_Parameter (Old_First),
+                       Relocate_Node (R));
+                  end if;
+
+               else
+                  Rewrite (Old_First, Relocate_Node (L));
+               end if;
+
+               if Nkind (Old_Sec) = N_Parameter_Association then
+                  if Chars (Selector_Name (Old_Sec))  =
+                     Chars (First_Entity (Op_Id))
+                  then
+                     Rewrite (Explicit_Actual_Parameter (Old_Sec),
+                       Relocate_Node (L));
+                  else
+                     Rewrite (Explicit_Actual_Parameter (Old_Sec),
+                       Relocate_Node (R));
+                  end if;
+
+               else
+                  Rewrite (Old_Sec, Relocate_Node (R));
+               end if;
+
+            else
+               if Nkind (Old_First) = N_Parameter_Association then
+                  Rewrite (Explicit_Actual_Parameter (Old_First),
+                    Relocate_Node (R));
+               else
+                  Rewrite (Old_First, Relocate_Node (R));
+               end if;
+            end if;
+         end;
+
          Set_Parent (Original_Node (N), Parent (N));
       end if;
    end Make_Call_Into_Operator;