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.
This commit is contained in:
Tom Tromey
2021-07-01 11:15:41 -06:00
parent cd4583499f
commit 8b12db26d1
3 changed files with 42 additions and 10 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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,