Introduce rust_range_operation
[binutils-gdb.git] / gdb / rust-exp.h
1 /* Definitions for Rust expressions
2
3 Copyright (C) 2020 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 *eval_op_rust_ind (struct type *expect_type,
37 struct expression *exp,
38 enum noside noside,
39 enum exp_opcode opcode,
40 struct value *value);
41 extern struct value *rust_subscript (struct type *expect_type,
42 struct expression *exp,
43 enum noside noside, bool for_addr,
44 struct value *lhs, struct value *rhs);
45 extern struct value *rust_range (struct type *expect_type,
46 struct expression *exp,
47 enum noside noside, enum range_flag kind,
48 struct value *low, struct value *high);
49
50 namespace expr
51 {
52
53 using rust_unop_compl_operation = unop_operation<UNOP_COMPLEMENT,
54 eval_op_rust_complement>;
55 using rust_array_operation = binop_operation<OP_RUST_ARRAY,
56 eval_op_rust_array>;
57
58 /* The Rust indirection operation. */
59 class rust_unop_ind_operation
60 : public unop_ind_operation
61 {
62 public:
63
64 using unop_ind_operation::unop_ind_operation;
65
66 value *evaluate (struct type *expect_type,
67 struct expression *exp,
68 enum noside noside) override
69 {
70 if (noside != EVAL_NORMAL)
71 return unop_ind_operation::evaluate (expect_type, exp, noside);
72
73 value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
74 return eval_op_rust_ind (expect_type, exp, noside, UNOP_IND, arg1);
75 }
76 };
77
78 /* Subscript operator for Rust. */
79 class rust_subscript_operation
80 : public tuple_holding_operation<operation_up, operation_up>
81 {
82 public:
83
84 using tuple_holding_operation::tuple_holding_operation;
85
86 value *evaluate (struct type *expect_type,
87 struct expression *exp,
88 enum noside noside) override
89 {
90 value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
91 value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
92 return rust_subscript (expect_type, exp, noside, false, arg1, arg2);
93 }
94
95 value *slice (struct type *expect_type,
96 struct expression *exp,
97 enum noside noside)
98 {
99 value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
100 value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
101 return rust_subscript (expect_type, exp, noside, true, arg1, arg2);
102 }
103
104 enum exp_opcode opcode () const override
105 { return BINOP_SUBSCRIPT; }
106 };
107
108 class rust_unop_addr_operation
109 : public tuple_holding_operation<operation_up>
110 {
111 public:
112
113 using tuple_holding_operation::tuple_holding_operation;
114
115 value *evaluate (struct type *expect_type,
116 struct expression *exp,
117 enum noside noside) override
118 {
119 operation *oper = std::get<0> (m_storage).get ();
120 rust_subscript_operation *sub_op
121 = dynamic_cast<rust_subscript_operation *> (oper);
122 if (sub_op != nullptr)
123 return sub_op->slice (expect_type, exp, noside);
124 return oper->evaluate_for_address (exp, noside);
125 }
126
127 enum exp_opcode opcode () const override
128 { return UNOP_ADDR; }
129 };
130
131 /* The Rust range operators. */
132 class rust_range_operation
133 : public tuple_holding_operation<enum range_flag, operation_up, operation_up>
134 {
135 public:
136
137 using tuple_holding_operation::tuple_holding_operation;
138
139 value *evaluate (struct type *expect_type,
140 struct expression *exp,
141 enum noside noside) override
142 {
143 auto kind = std::get<0> (m_storage);
144 value *low = nullptr;
145 if (std::get<1> (m_storage) != nullptr)
146 low = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
147 value *high = nullptr;
148 if (std::get<2> (m_storage) != nullptr)
149 high = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
150 return rust_range (expect_type, exp, noside, kind, low, high);
151 }
152
153 enum exp_opcode opcode () const override
154 { return OP_RANGE; }
155 };
156
157 } /* namespace expr */
158
159 #endif /* RUST_EXP_H */