X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fada-exp.h;h=d85349c7fcce09adc1c0f7c47f59b17d4cc3ee41;hb=387e00f3b3e6ea3719f144d7090c1a242174be4d;hp=96e3c407b6fa9f321397b7928f64d8c68995d79a;hpb=1b1ebfab47433232078d9352d6d5ebd7baee1850;p=binutils-gdb.git diff --git a/gdb/ada-exp.h b/gdb/ada-exp.h index 96e3c407b6f..d85349c7fcc 100644 --- a/gdb/ada-exp.h +++ b/gdb/ada-exp.h @@ -1,6 +1,6 @@ /* Definitions for Ada expressions - Copyright (C) 2020 Free Software Foundation, Inc. + Copyright (C) 2020-2022 Free Software Foundation, Inc. This file is part of GDB. @@ -55,10 +55,66 @@ extern struct value *ada_ternop_slice (struct expression *exp, struct value *array, struct value *low_bound_val, struct value *high_bound_val); +extern struct value *ada_binop_in_bounds (struct expression *exp, + enum noside noside, + struct value *arg1, + struct value *arg2, + int n); +extern struct value *ada_binop_minmax (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg1, + struct value *arg2); +extern struct value *ada_pos_atr (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg); +extern struct value *ada_val_atr (enum noside noside, struct type *type, + struct value *arg); +extern struct value *ada_binop_exp (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg1, struct value *arg2); 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; + + /* 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 handles some Ada-specific type conversions. */ class ada_wrapped_operation @@ -84,6 +140,12 @@ public: using string_operation::string_operation; + /* Return the underlying string. */ + const char *get_name () const + { + return std::get<0> (m_storage).c_str (); + } + value *evaluate (struct type *expect_type, struct expression *exp, enum noside noside) override; @@ -125,6 +187,7 @@ using ada_neg_operation = unop_operation; using ada_atr_tag_operation = unop_operation; using ada_atr_size_operation = unop_operation; using ada_abs_operation = unop_operation; +using ada_pos_operation = unop_operation; /* The in-range operation, given a type. */ class ada_unop_range_operation @@ -168,6 +231,11 @@ using ada_binop_div_operation = binop_operation; using ada_binop_rem_operation = binop_operation; using ada_binop_mod_operation = binop_operation; +using ada_binop_min_operation = binop_operation; +using ada_binop_max_operation = binop_operation; + +using ada_binop_exp_operation = binop_operation; + /* Implement the equal and not-equal operations for Ada. */ class ada_binop_equal_operation : public tuple_holding_operation @@ -220,7 +288,8 @@ using ada_bitwise_xor_operation = ada_bitwise_operation; /* Ada array- or string-slice operation. */ class ada_ternop_slice_operation - : public maybe_constant_operation + : public maybe_constant_operation, + public ada_resolvable { public: @@ -238,6 +307,506 @@ 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. */ +class ada_binop_in_bounds_operation + : public maybe_constant_operation +{ +public: + + using maybe_constant_operation::maybe_constant_operation; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override + { + value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); + value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); + return ada_binop_in_bounds (exp, noside, arg1, arg2, + std::get<2> (m_storage)); + } + + enum exp_opcode opcode () const override + { return BINOP_IN_BOUNDS; } +}; + +/* Implement several unary Ada OP_ATR_* operations. */ +class ada_unop_atr_operation + : public maybe_constant_operation +{ +public: + + using maybe_constant_operation::maybe_constant_operation; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override; + + enum exp_opcode opcode () const override + { return std::get<1> (m_storage); } +}; + +/* Variant of var_value_operation for Ada. */ +class ada_var_value_operation + : public var_value_operation, public ada_resolvable +{ +public: + + using var_value_operation::var_value_operation; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override; + + value *evaluate_for_cast (struct type *expect_type, + struct expression *exp, + enum noside noside) override; + + const block *get_block () const + { return std::get<0> (m_storage).block; } + + 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; +}; + +/* Variant of var_msym_value_operation for Ada. */ +class ada_var_msym_value_operation + : public var_msym_value_operation +{ +public: + + using var_msym_value_operation::var_msym_value_operation; + + value *evaluate_for_cast (struct type *expect_type, + struct expression *exp, + enum noside noside) override; + +protected: + + using operation::do_generate_ax; +}; + +/* Implement the Ada 'val attribute. */ +class ada_atr_val_operation + : public tuple_holding_operation +{ +public: + + using tuple_holding_operation::tuple_holding_operation; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override; + + enum exp_opcode opcode () const override + { return OP_ATR_VAL; } +}; + +/* The indirection operator for Ada. */ +class ada_unop_ind_operation + : public unop_ind_base_operation +{ +public: + + using unop_ind_base_operation::unop_ind_base_operation; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override; +}; + +/* Implement STRUCTOP_STRUCT for Ada. */ +class ada_structop_operation + : public structop_base_operation +{ +public: + + using structop_base_operation::structop_base_operation; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override; + + enum exp_opcode opcode () const override + { return STRUCTOP_STRUCT; } + + /* Set the completion prefix. */ + void set_prefix (std::string &&prefix) + { + m_prefix = std::move (prefix); + } + + bool complete (struct expression *exp, completion_tracker &tracker) override + { + return structop_base_operation::complete (exp, tracker, m_prefix.c_str ()); + } + + void dump (struct ui_file *stream, int depth) const override + { + structop_base_operation::dump (stream, depth); + dump_for_expression (stream, depth + 1, m_prefix); + } + +private: + + /* We may need to provide a prefix to field name completion. See + ada-exp.y:find_completion_bounds for details. */ + std::string m_prefix; +}; + +/* Function calls for Ada. */ +class ada_funcall_operation + : public tuple_holding_operation>, + public ada_resolvable +{ +public: + + using tuple_holding_operation::tuple_holding_operation; + + value *evaluate (struct type *expect_type, + 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; } +}; + +/* An Ada assignment operation. */ +class ada_assign_operation + : public assign_operation +{ +public: + + using assign_operation::assign_operation; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override; + + enum exp_opcode opcode () const override + { return BINOP_ASSIGN; } +}; + +/* This abstract class represents a single component in an Ada + aggregate assignment. */ +class ada_component +{ +public: + + /* Assign to LHS, which is part of CONTAINER. EXP is the expression + being evaluated. INDICES, LOW, and HIGH indicate which + sub-components have already been assigned; INDICES should be + updated by this call. */ + virtual void assign (struct value *container, + struct value *lhs, struct expression *exp, + std::vector &indices, + LONGEST low, LONGEST high) = 0; + + /* Same as operation::uses_objfile. */ + virtual bool uses_objfile (struct objfile *objfile) = 0; + + /* Same as operation::dump. */ + virtual void dump (ui_file *stream, int depth) = 0; + + virtual ~ada_component () = default; + +protected: + + ada_component () = default; + DISABLE_COPY_AND_ASSIGN (ada_component); +}; + +/* Unique pointer specialization for Ada assignment components. */ +typedef std::unique_ptr ada_component_up; + +/* An operation that holds a single component. */ +class ada_aggregate_operation + : public tuple_holding_operation +{ +public: + + using tuple_holding_operation::tuple_holding_operation; + + /* Assuming that LHS represents an lvalue having a record or array + type, evaluate an assignment of this aggregate's value to LHS. + CONTAINER is an lvalue containing LHS (possibly LHS itself). + Does not modify the inferior's memory, nor does it modify the + contents of LHS (unless == CONTAINER). Returns the modified + CONTAINER. */ + + value *assign_aggregate (struct value *container, + struct value *lhs, + struct expression *exp); + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override + { + error (_("Aggregates only allowed on the right of an assignment")); + } + + enum exp_opcode opcode () const override + { return OP_AGGREGATE; } +}; + +/* A component holding a vector of other components to assign. */ +class ada_aggregate_component : public ada_component +{ +public: + + explicit ada_aggregate_component (std::vector &&components) + : m_components (std::move (components)) + { + } + + void assign (struct value *container, + struct value *lhs, struct expression *exp, + std::vector &indices, + LONGEST low, LONGEST high) override; + + bool uses_objfile (struct objfile *objfile) override; + + void dump (ui_file *stream, int depth) override; + +private: + + std::vector m_components; +}; + +/* A component that assigns according to a provided index (which is + relative to the "low" value). */ +class ada_positional_component : public ada_component +{ +public: + + ada_positional_component (int index, operation_up &&op) + : m_index (index), + m_op (std::move (op)) + { + } + + void assign (struct value *container, + struct value *lhs, struct expression *exp, + std::vector &indices, + LONGEST low, LONGEST high) override; + + bool uses_objfile (struct objfile *objfile) override; + + void dump (ui_file *stream, int depth) override; + +private: + + int m_index; + operation_up m_op; +}; + +/* A component which handles an "others" clause. */ +class ada_others_component : public ada_component +{ +public: + + explicit ada_others_component (operation_up &&op) + : m_op (std::move (op)) + { + } + + void assign (struct value *container, + struct value *lhs, struct expression *exp, + std::vector &indices, + LONGEST low, LONGEST high) override; + + bool uses_objfile (struct objfile *objfile) override; + + void dump (ui_file *stream, int depth) override; + +private: + + operation_up m_op; +}; + +/* An interface that represents an association that is used in + aggregate assignment. */ +class ada_association +{ +public: + + /* Like ada_component::assign, but takes an operation as a + parameter. The operation is evaluated and then assigned into LHS + according to the rules of the concrete implementation. */ + virtual void assign (struct value *container, + struct value *lhs, + struct expression *exp, + std::vector &indices, + LONGEST low, LONGEST high, + operation_up &op) = 0; + + /* Same as operation::uses_objfile. */ + virtual bool uses_objfile (struct objfile *objfile) = 0; + + /* Same as operation::dump. */ + virtual void dump (ui_file *stream, int depth) = 0; + + virtual ~ada_association () = default; + +protected: + + ada_association () = default; + DISABLE_COPY_AND_ASSIGN (ada_association); +}; + +/* Unique pointer specialization for Ada assignment associations. */ +typedef std::unique_ptr ada_association_up; + +/* A component that holds a vector of associations and an operation. + The operation is re-evaluated for each choice. */ +class ada_choices_component : public ada_component +{ +public: + + explicit ada_choices_component (operation_up &&op) + : m_op (std::move (op)) + { + } + + /* Set the vector of associations. This is done separately from the + constructor because it was simpler for the implementation of the + parser. */ + void set_associations (std::vector &&assoc) + { + m_assocs = std::move (assoc); + } + + void assign (struct value *container, + struct value *lhs, struct expression *exp, + std::vector &indices, + LONGEST low, LONGEST high) override; + + bool uses_objfile (struct objfile *objfile) override; + + void dump (ui_file *stream, int depth) override; + +private: + + std::vector m_assocs; + operation_up m_op; +}; + +/* An association that uses a discrete range. */ +class ada_discrete_range_association : public ada_association +{ +public: + + ada_discrete_range_association (operation_up &&low, operation_up &&high) + : m_low (std::move (low)), + m_high (std::move (high)) + { + } + + void assign (struct value *container, + struct value *lhs, struct expression *exp, + std::vector &indices, + LONGEST low, LONGEST high, + operation_up &op) override; + + bool uses_objfile (struct objfile *objfile) override; + + void dump (ui_file *stream, int depth) override; + +private: + + operation_up m_low; + operation_up m_high; +}; + +/* An association that uses a name. The name may be an expression + that evaluates to an integer (for arrays), or an Ada string or + variable value operation. */ +class ada_name_association : public ada_association +{ +public: + + explicit ada_name_association (operation_up val) + : m_val (std::move (val)) + { + } + + void assign (struct value *container, + struct value *lhs, struct expression *exp, + std::vector &indices, + LONGEST low, LONGEST high, + operation_up &op) override; + + bool uses_objfile (struct objfile *objfile) override; + + void dump (ui_file *stream, int depth) override; + +private: + + operation_up m_val; +}; + +/* A character constant expression. This is a separate operation so + that it can participate in resolution, so that TYPE'(CST) can + work correctly for enums with character enumerators. */ +class ada_char_operation : public long_const_operation, + public ada_resolvable +{ +public: + + using long_const_operation::long_const_operation; + + bool resolve (struct expression *exp, + bool deprocedure_p, + bool parse_completion, + innermost_block_tracker *tracker, + struct type *context_type) override + { + /* This should never be called, because this class also implements + 'replace'. */ + gdb_assert_not_reached ("unexpected call"); + } + + operation_up replace (operation_up &&owner, + struct expression *exp, + bool deprocedure_p, + bool parse_completion, + innermost_block_tracker *tracker, + struct type *context_type) override; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override; +}; + +class ada_concat_operation : public concat_operation +{ +public: + + using concat_operation::concat_operation; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override; }; } /* namespace expr */