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