From 8b12db26d161d526953ab04ad92d598fd148d0bf Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey@adacore.com>
Date: Thu, 1 Jul 2021 11:15:41 -0600
Subject: Refactor Ada resolution

In a subsequent patch, it will be convenient if an Ada expression
operation can supply its own replacement object.  This patch refactors
Ada expression resolution to make this possible.
---
 gdb/ada-exp.h  | 18 ++++++++++++++++++
 gdb/ada-exp.y  | 17 +++++++----------
 gdb/ada-lang.c | 17 +++++++++++++++++
 3 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/gdb/ada-exp.h b/gdb/ada-exp.h
index 598dc70..e600ec2 100644
--- a/gdb/ada-exp.h
+++ b/gdb/ada-exp.h
@@ -95,6 +95,24 @@ struct ada_resolvable
 			bool parse_completion,
 			innermost_block_tracker *tracker,
 			struct type *context_type) = 0;
+
+  /* Possibly replace this object with some other expression object.
+     This is like 'resolve', but can return a replacement.
+
+     The default implementation calls 'resolve' and wraps this object
+     in a function call if that call returns true.  OWNER is a
+     reference to the unique pointer that owns the 'this'; it can be
+     'move'd from to construct the replacement.
+
+     This should either return a new object, or OWNER -- never
+     nullptr.  */
+
+  virtual operation_up replace (operation_up &&owner,
+				struct expression *exp,
+				bool deprocedure_p,
+				bool parse_completion,
+				innermost_block_tracker *tracker,
+				struct type *context_type);
 };
 
 /* In Ada, some generic operations must be wrapped with a handler that
diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
index 5b6aca9..afa085e 100644
--- a/gdb/ada-exp.y
+++ b/gdb/ada-exp.y
@@ -119,16 +119,13 @@ resolve (operation_up &&op, bool deprocedure_p, struct type *context_type)
 {
   operation_up result = std::move (op);
   ada_resolvable *res = dynamic_cast<ada_resolvable *> (result.get ());
-  if (res != nullptr
-      && res->resolve (pstate->expout.get (),
-		       deprocedure_p,
-		       pstate->parse_completion,
-		       pstate->block_tracker,
-		       context_type))
-    result
-      = make_operation<ada_funcall_operation> (std::move (result),
-					       std::vector<operation_up> ());
-
+  if (res != nullptr)
+    return res->replace (std::move (result),
+			 pstate->expout.get (),
+			 deprocedure_p,
+			 pstate->parse_completion,
+			 pstate->block_tracker,
+			 context_type);
   return result;
 }
 
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index f45384a..a435543 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10097,6 +10097,23 @@ ada_binop_exp (struct type *expect_type,
 namespace expr
 {
 
+/* See ada-exp.h.  */
+
+operation_up
+ada_resolvable::replace (operation_up &&owner,
+			 struct expression *exp,
+			 bool deprocedure_p,
+			 bool parse_completion,
+			 innermost_block_tracker *tracker,
+			 struct type *context_type)
+{
+  if (resolve (exp, deprocedure_p, parse_completion, tracker, context_type))
+    return (make_operation<ada_funcall_operation>
+	    (std::move (owner),
+	     std::vector<operation_up> ()));
+  return std::move (owner);
+}
+
 value *
 ada_wrapped_operation::evaluate (struct type *expect_type,
 				 struct expression *exp,
-- 
cgit v1.1