Home | History | Annotate | Line # | Download | only in gdb
rust-exp.h revision 1.1.1.1.4.2
      1 /* Definitions for Rust expressions
      2 
      3    Copyright (C) 2020-2023 Free Software Foundation, Inc.
      4 
      5    This file is part of GDB.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19 
     20 #ifndef RUST_EXP_H
     21 #define RUST_EXP_H
     22 
     23 #include "expop.h"
     24 
     25 extern struct value *eval_op_rust_complement (struct type *expect_type,
     26 					      struct expression *exp,
     27 					      enum noside noside,
     28 					      enum exp_opcode opcode,
     29 					      struct value *value);
     30 extern struct value *eval_op_rust_array (struct type *expect_type,
     31 					 struct expression *exp,
     32 					 enum noside noside,
     33 					 enum exp_opcode opcode,
     34 					 struct value *ncopies,
     35 					 struct value *elt);
     36 extern struct value *rust_subscript (struct type *expect_type,
     37 				     struct expression *exp,
     38 				     enum noside noside, bool for_addr,
     39 				     struct value *lhs, struct value *rhs);
     40 extern struct value *rust_range (struct type *expect_type,
     41 				 struct expression *exp,
     42 				 enum noside noside, enum range_flag kind,
     43 				 struct value *low, struct value *high);
     44 
     45 namespace expr
     46 {
     47 
     48 using rust_unop_compl_operation = unop_operation<UNOP_COMPLEMENT,
     49 						  eval_op_rust_complement>;
     50 using rust_array_operation = binop_operation<OP_RUST_ARRAY,
     51 					     eval_op_rust_array>;
     52 
     53 /* The Rust indirection operation.  */
     54 class rust_unop_ind_operation
     55   : public unop_ind_operation
     56 {
     57 public:
     58 
     59   using unop_ind_operation::unop_ind_operation;
     60 
     61   value *evaluate (struct type *expect_type,
     62 		   struct expression *exp,
     63 		   enum noside noside) override;
     64 };
     65 
     66 /* Subscript operator for Rust.  */
     67 class rust_subscript_operation
     68   : public tuple_holding_operation<operation_up, operation_up>
     69 {
     70 public:
     71 
     72   using tuple_holding_operation::tuple_holding_operation;
     73 
     74   value *evaluate (struct type *expect_type,
     75 		   struct expression *exp,
     76 		   enum noside noside) override
     77   {
     78     value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
     79     value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
     80     return rust_subscript (expect_type, exp, noside, false, arg1, arg2);
     81   }
     82 
     83   value *slice (struct type *expect_type,
     84 		struct expression *exp,
     85 		enum noside noside)
     86   {
     87     value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
     88     value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
     89     return rust_subscript (expect_type, exp, noside, true, arg1, arg2);
     90   }
     91 
     92   enum exp_opcode opcode () const override
     93   { return BINOP_SUBSCRIPT; }
     94 };
     95 
     96 class rust_unop_addr_operation
     97   : public tuple_holding_operation<operation_up>
     98 {
     99 public:
    100 
    101   using tuple_holding_operation::tuple_holding_operation;
    102 
    103   value *evaluate (struct type *expect_type,
    104 		   struct expression *exp,
    105 		   enum noside noside) override
    106   {
    107     operation *oper = std::get<0> (m_storage).get ();
    108     rust_subscript_operation *sub_op
    109       = dynamic_cast<rust_subscript_operation *> (oper);
    110     if (sub_op != nullptr)
    111       return sub_op->slice (expect_type, exp, noside);
    112     return oper->evaluate_for_address (exp, noside);
    113   }
    114 
    115   enum exp_opcode opcode () const override
    116   { return UNOP_ADDR; }
    117 };
    118 
    119 /* The Rust range operators.  */
    120 class rust_range_operation
    121   : public tuple_holding_operation<enum range_flag, operation_up, operation_up>
    122 {
    123 public:
    124 
    125   using tuple_holding_operation::tuple_holding_operation;
    126 
    127   value *evaluate (struct type *expect_type,
    128 		   struct expression *exp,
    129 		   enum noside noside) override
    130   {
    131     auto kind = std::get<0> (m_storage);
    132     value *low = nullptr;
    133     if (std::get<1> (m_storage) != nullptr)
    134       low = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
    135     value *high = nullptr;
    136     if (std::get<2> (m_storage) != nullptr)
    137       high = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
    138     return rust_range (expect_type, exp, noside, kind, low, high);
    139   }
    140 
    141   enum exp_opcode opcode () const override
    142   { return OP_RANGE; }
    143 };
    144 
    145 /* Tuple field reference (using an integer).  */
    146 class rust_struct_anon
    147   : public tuple_holding_operation<int, operation_up>
    148 {
    149 public:
    150 
    151   using tuple_holding_operation::tuple_holding_operation;
    152 
    153   value *evaluate (struct type *expect_type,
    154 		   struct expression *exp,
    155 		   enum noside noside) override;
    156 
    157   enum exp_opcode opcode () const override
    158   { return STRUCTOP_ANONYMOUS; }
    159 };
    160 
    161 /* Structure (or union or enum) field reference.  */
    162 class rust_structop
    163   : public structop_base_operation
    164 {
    165 public:
    166 
    167   using structop_base_operation::structop_base_operation;
    168 
    169   value *evaluate (struct type *expect_type,
    170 		   struct expression *exp,
    171 		   enum noside noside) override;
    172 
    173   value *evaluate_funcall (struct type *expect_type,
    174 			   struct expression *exp,
    175 			   enum noside noside,
    176 			   const std::vector<operation_up> &args) override;
    177 
    178   enum exp_opcode opcode () const override
    179   { return STRUCTOP_STRUCT; }
    180 };
    181 
    182 /* Rust aggregate initialization.  */
    183 class rust_aggregate_operation
    184   : public tuple_holding_operation<struct type *, operation_up,
    185 				   std::vector<std::pair<std::string,
    186 							 operation_up>>>
    187 {
    188 public:
    189 
    190   using tuple_holding_operation::tuple_holding_operation;
    191 
    192   value *evaluate (struct type *expect_type,
    193 		   struct expression *exp,
    194 		   enum noside noside) override;
    195 
    196   enum exp_opcode opcode () const override
    197   { return OP_AGGREGATE; }
    198 };
    199 
    200 /* Rust parenthesized operation.  This is needed to distinguish
    201    between 'obj.f()', which is a method call, and '(obj.f)()', which
    202    is a call of a function-valued field 'f'.  */
    203 class rust_parenthesized_operation
    204   : public tuple_holding_operation<operation_up>
    205 {
    206 public:
    207 
    208   explicit rust_parenthesized_operation (operation_up op)
    209     : tuple_holding_operation (std::move (op))
    210   {
    211   }
    212 
    213   value *evaluate (struct type *expect_type,
    214 		   struct expression *exp,
    215 		   enum noside noside) override
    216   {
    217     return std::get<0> (m_storage)->evaluate (expect_type, exp, noside);
    218   }
    219 
    220   enum exp_opcode opcode () const override
    221   {
    222     /* A lie but this isn't worth introducing a new opcode for.  */
    223     return UNOP_PLUS;
    224   }
    225 };
    226 
    227 } /* namespace expr */
    228 
    229 #endif /* RUST_EXP_H */
    230