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