aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog13
-rw-r--r--gdb/ada-exp.h47
-rw-r--r--gdb/ada-lang.c79
3 files changed, 136 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4738350..c770a0d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,18 @@
2021-03-08 Tom Tromey <tom@tromey.com>
+ * ada-lang.c (ada_var_value_operation::resolve)
+ (ada_funcall_operation::resolve)
+ (ada_ternop_slice_operation::resolve): New methods.
+ * ada-exp.h (struct ada_resolvable): New.
+ (class ada_var_value_operation): Derive from ada_resolvable.
+ <get_block, resolve>: New methods.
+ (class ada_funcall_operation): Derive from ada_resolvable.
+ <resolve>: New method.
+ (class ada_ternop_slice_operation): Derive from ada_resolvable.
+ <resolve>: New method.
+
+2021-03-08 Tom Tromey <tom@tromey.com>
+
* ada-lang.c (ada_funcall_operation::evaluate): New method.
* ada-exp.h (class ada_var_msym_value_operation) <get_symbol>: New
method.
diff --git a/gdb/ada-exp.h b/gdb/ada-exp.h
index 287ed5c..456aa89 100644
--- a/gdb/ada-exp.h
+++ b/gdb/ada-exp.h
@@ -79,6 +79,24 @@ extern struct value *ada_binop_exp (struct type *expect_type,
namespace expr
{
+/* The base class for Ada type resolution. Ada operations that want
+ to participate in resolution implement this interface. */
+struct ada_resolvable
+{
+ /* Resolve this object. EXP is the expression being resolved.
+ DEPROCEDURE_P is true if a symbol that refers to a zero-argument
+ function may be turned into a function call. PARSE_COMPLETION
+ and TRACKER are passed in from the parser context. CONTEXT_TYPE
+ is the expected type of the expression, or nullptr if none is
+ known. This method should return true if the operation should be
+ replaced by a function call with this object as the callee. */
+ virtual bool resolve (struct expression *exp,
+ bool deprocedure_p,
+ bool parse_completion,
+ innermost_block_tracker *tracker,
+ struct type *context_type) = 0;
+};
+
/* In Ada, some generic operations must be wrapped with a handler that
handles some Ada-specific type conversions. */
class ada_wrapped_operation
@@ -246,7 +264,8 @@ using ada_bitwise_xor_operation = ada_bitwise_operation<BINOP_BITWISE_XOR>;
/* Ada array- or string-slice operation. */
class ada_ternop_slice_operation
- : public maybe_constant_operation<operation_up, operation_up, operation_up>
+ : public maybe_constant_operation<operation_up, operation_up, operation_up>,
+ public ada_resolvable
{
public:
@@ -264,6 +283,12 @@ public:
enum exp_opcode opcode () const override
{ return TERNOP_SLICE; }
+
+ bool resolve (struct expression *exp,
+ bool deprocedure_p,
+ bool parse_completion,
+ innermost_block_tracker *tracker,
+ struct type *context_type) override;
};
/* Implement BINOP_IN_BOUNDS for Ada. */
@@ -306,7 +331,7 @@ public:
/* Variant of var_value_operation for Ada. */
class ada_var_value_operation
- : public var_value_operation
+ : public var_value_operation, public ada_resolvable
{
public:
@@ -323,6 +348,15 @@ public:
symbol *get_symbol () const
{ return std::get<0> (m_storage); }
+ const block *get_block () const
+ { return std::get<1> (m_storage); }
+
+ bool resolve (struct expression *exp,
+ bool deprocedure_p,
+ bool parse_completion,
+ innermost_block_tracker *tracker,
+ struct type *context_type) override;
+
protected:
using operation::do_generate_ax;
@@ -392,7 +426,8 @@ public:
/* Function calls for Ada. */
class ada_funcall_operation
- : public tuple_holding_operation<operation_up, std::vector<operation_up>>
+ : public tuple_holding_operation<operation_up, std::vector<operation_up>>,
+ public ada_resolvable
{
public:
@@ -402,6 +437,12 @@ public:
struct expression *exp,
enum noside noside) override;
+ bool resolve (struct expression *exp,
+ bool deprocedure_p,
+ bool parse_completion,
+ innermost_block_tracker *tracker,
+ struct type *context_type) override;
+
enum exp_opcode opcode () const override
{ return OP_FUNCALL; }
};
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 2bee8ab..261c917 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10694,6 +10694,31 @@ ada_var_value_operation::evaluate (struct type *expect_type,
return ada_to_fixed_value (arg1);
}
+bool
+ada_var_value_operation::resolve (struct expression *exp,
+ bool deprocedure_p,
+ bool parse_completion,
+ innermost_block_tracker *tracker,
+ struct type *context_type)
+{
+ symbol *sym = std::get<0> (m_storage);
+ if (SYMBOL_DOMAIN (sym) == UNDEF_DOMAIN)
+ {
+ block_symbol resolved
+ = ada_resolve_variable (sym, std::get<1> (m_storage),
+ context_type, parse_completion,
+ deprocedure_p, tracker);
+ std::get<0> (m_storage) = resolved.symbol;
+ std::get<1> (m_storage) = resolved.block;
+ }
+
+ if (deprocedure_p
+ && SYMBOL_TYPE (std::get<0> (m_storage))->code () == TYPE_CODE_FUNC)
+ return true;
+
+ return false;
+}
+
value *
ada_atr_val_operation::evaluate (struct type *expect_type,
struct expression *exp,
@@ -10972,6 +10997,60 @@ ada_funcall_operation::evaluate (struct type *expect_type,
}
}
+bool
+ada_funcall_operation::resolve (struct expression *exp,
+ bool deprocedure_p,
+ bool parse_completion,
+ innermost_block_tracker *tracker,
+ struct type *context_type)
+{
+ operation_up &callee_op = std::get<0> (m_storage);
+
+ ada_var_value_operation *avv
+ = dynamic_cast<ada_var_value_operation *> (callee_op.get ());
+ if (avv == nullptr)
+ return false;
+
+ symbol *sym = avv->get_symbol ();
+ if (SYMBOL_DOMAIN (sym) != UNDEF_DOMAIN)
+ return false;
+
+ const std::vector<operation_up> &args_up = std::get<1> (m_storage);
+ int nargs = args_up.size ();
+ std::vector<value *> argvec (nargs);
+
+ for (int i = 0; i < args_up.size (); ++i)
+ argvec[i] = args_up[i]->evaluate (nullptr, exp, EVAL_AVOID_SIDE_EFFECTS);
+
+ const block *block = avv->get_block ();
+ block_symbol resolved
+ = ada_resolve_funcall (sym, block,
+ context_type, parse_completion,
+ nargs, argvec.data (),
+ tracker);
+
+ std::get<0> (m_storage)
+ = make_operation<ada_var_value_operation> (resolved.symbol,
+ resolved.block);
+ return false;
+}
+
+bool
+ada_ternop_slice_operation::resolve (struct expression *exp,
+ bool deprocedure_p,
+ bool parse_completion,
+ innermost_block_tracker *tracker,
+ struct type *context_type)
+{
+ /* Historically this check was done during resolution, so we
+ continue that here. */
+ value *v = std::get<0> (m_storage)->evaluate (context_type, exp,
+ EVAL_AVOID_SIDE_EFFECTS);
+ if (ada_is_any_packed_array_type (value_type (v)))
+ error (_("cannot slice a packed array"));
+ return false;
+}
+
}
/* Implement the evaluate_exp routine in the exp_descriptor structure