xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/rust-exp.h (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
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