]>
Commit | Line | Data |
---|---|---|
03070ee9 TT |
1 | /* Definitions for Ada expressions |
2 | ||
1d506c26 | 3 | Copyright (C) 2020-2024 Free Software Foundation, Inc. |
03070ee9 TT |
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 ADA_EXP_H | |
21 | #define ADA_EXP_H | |
22 | ||
23 | #include "expop.h" | |
24 | ||
7c15d377 TT |
25 | extern struct value *ada_unop_neg (struct type *expect_type, |
26 | struct expression *exp, | |
27 | enum noside noside, enum exp_opcode op, | |
28 | struct value *arg1); | |
29 | extern struct value *ada_atr_tag (struct type *expect_type, | |
30 | struct expression *exp, | |
31 | enum noside noside, enum exp_opcode op, | |
32 | struct value *arg1); | |
33 | extern struct value *ada_atr_size (struct type *expect_type, | |
34 | struct expression *exp, | |
35 | enum noside noside, enum exp_opcode op, | |
36 | struct value *arg1); | |
37 | extern struct value *ada_abs (struct type *expect_type, | |
38 | struct expression *exp, | |
39 | enum noside noside, enum exp_opcode op, | |
40 | struct value *arg1); | |
95d49dfb TT |
41 | extern struct value *ada_unop_in_range (struct type *expect_type, |
42 | struct expression *exp, | |
43 | enum noside noside, enum exp_opcode op, | |
44 | struct value *arg1, struct type *type); | |
d9e7db06 TT |
45 | extern struct value *ada_mult_binop (struct type *expect_type, |
46 | struct expression *exp, | |
47 | enum noside noside, enum exp_opcode op, | |
48 | struct value *arg1, struct value *arg2); | |
6e8fb7b7 TT |
49 | extern struct value *ada_equal_binop (struct type *expect_type, |
50 | struct expression *exp, | |
51 | enum noside noside, enum exp_opcode op, | |
52 | struct value *arg1, struct value *arg2); | |
1b1ebfab TT |
53 | extern struct value *ada_ternop_slice (struct expression *exp, |
54 | enum noside noside, | |
55 | struct value *array, | |
56 | struct value *low_bound_val, | |
57 | struct value *high_bound_val); | |
82c3886e TT |
58 | extern struct value *ada_binop_in_bounds (struct expression *exp, |
59 | enum noside noside, | |
60 | struct value *arg1, | |
61 | struct value *arg2, | |
62 | int n); | |
6ad3b8bf TT |
63 | extern struct value *ada_binop_minmax (struct type *expect_type, |
64 | struct expression *exp, | |
65 | enum noside noside, enum exp_opcode op, | |
66 | struct value *arg1, | |
67 | struct value *arg2); | |
7631cf6c TT |
68 | extern struct value *ada_pos_atr (struct type *expect_type, |
69 | struct expression *exp, | |
70 | enum noside noside, enum exp_opcode op, | |
71 | struct value *arg); | |
22f6f797 TT |
72 | extern struct value *ada_atr_enum_rep (struct expression *exp, |
73 | enum noside noside, struct type *type, | |
74 | struct value *arg); | |
75 | extern struct value *ada_atr_enum_val (struct expression *exp, | |
76 | enum noside noside, struct type *type, | |
77 | struct value *arg); | |
78 | extern struct value *ada_val_atr (struct expression *exp, | |
79 | enum noside noside, struct type *type, | |
9e99f48f | 80 | struct value *arg); |
065ec826 TT |
81 | extern struct value *ada_binop_exp (struct type *expect_type, |
82 | struct expression *exp, | |
83 | enum noside noside, enum exp_opcode op, | |
84 | struct value *arg1, struct value *arg2); | |
7c15d377 | 85 | |
03070ee9 TT |
86 | namespace expr |
87 | { | |
88 | ||
d8a4ed8a TT |
89 | /* The base class for Ada type resolution. Ada operations that want |
90 | to participate in resolution implement this interface. */ | |
91 | struct ada_resolvable | |
92 | { | |
93 | /* Resolve this object. EXP is the expression being resolved. | |
94 | DEPROCEDURE_P is true if a symbol that refers to a zero-argument | |
95 | function may be turned into a function call. PARSE_COMPLETION | |
96 | and TRACKER are passed in from the parser context. CONTEXT_TYPE | |
97 | is the expected type of the expression, or nullptr if none is | |
98 | known. This method should return true if the operation should be | |
99 | replaced by a function call with this object as the callee. */ | |
100 | virtual bool resolve (struct expression *exp, | |
101 | bool deprocedure_p, | |
102 | bool parse_completion, | |
103 | innermost_block_tracker *tracker, | |
104 | struct type *context_type) = 0; | |
8b12db26 TT |
105 | |
106 | /* Possibly replace this object with some other expression object. | |
107 | This is like 'resolve', but can return a replacement. | |
108 | ||
109 | The default implementation calls 'resolve' and wraps this object | |
110 | in a function call if that call returns true. OWNER is a | |
111 | reference to the unique pointer that owns the 'this'; it can be | |
112 | 'move'd from to construct the replacement. | |
113 | ||
114 | This should either return a new object, or OWNER -- never | |
115 | nullptr. */ | |
116 | ||
117 | virtual operation_up replace (operation_up &&owner, | |
118 | struct expression *exp, | |
119 | bool deprocedure_p, | |
120 | bool parse_completion, | |
121 | innermost_block_tracker *tracker, | |
122 | struct type *context_type); | |
d8a4ed8a TT |
123 | }; |
124 | ||
03070ee9 TT |
125 | /* In Ada, some generic operations must be wrapped with a handler that |
126 | handles some Ada-specific type conversions. */ | |
127 | class ada_wrapped_operation | |
128 | : public tuple_holding_operation<operation_up> | |
129 | { | |
130 | public: | |
131 | ||
132 | using tuple_holding_operation::tuple_holding_operation; | |
133 | ||
134 | value *evaluate (struct type *expect_type, | |
135 | struct expression *exp, | |
136 | enum noside noside) override; | |
137 | ||
138 | enum exp_opcode opcode () const override | |
139 | { return std::get<0> (m_storage)->opcode (); } | |
013a623f TT |
140 | |
141 | protected: | |
142 | ||
143 | void do_generate_ax (struct expression *exp, | |
144 | struct agent_expr *ax, | |
145 | struct axs_value *value, | |
146 | struct type *cast_type) | |
147 | override; | |
03070ee9 TT |
148 | }; |
149 | ||
42fecb61 TT |
150 | /* An Ada string constant. */ |
151 | class ada_string_operation | |
152 | : public string_operation | |
153 | { | |
154 | public: | |
155 | ||
156 | using string_operation::string_operation; | |
157 | ||
a88c4354 TT |
158 | /* Return the underlying string. */ |
159 | const char *get_name () const | |
160 | { | |
161 | return std::get<0> (m_storage).c_str (); | |
162 | } | |
163 | ||
42fecb61 TT |
164 | value *evaluate (struct type *expect_type, |
165 | struct expression *exp, | |
166 | enum noside noside) override; | |
167 | }; | |
168 | ||
cc6bd32e TT |
169 | /* The Ada TYPE'(EXP) construct. */ |
170 | class ada_qual_operation | |
171 | : public tuple_holding_operation<operation_up, struct type *> | |
172 | { | |
173 | public: | |
174 | ||
175 | using tuple_holding_operation::tuple_holding_operation; | |
176 | ||
177 | value *evaluate (struct type *expect_type, | |
178 | struct expression *exp, | |
179 | enum noside noside) override; | |
180 | ||
181 | enum exp_opcode opcode () const override | |
182 | { return UNOP_QUAL; } | |
183 | }; | |
184 | ||
fc715eb2 TT |
185 | /* Ternary in-range operator. */ |
186 | class ada_ternop_range_operation | |
187 | : public tuple_holding_operation<operation_up, operation_up, operation_up> | |
188 | { | |
189 | public: | |
190 | ||
191 | using tuple_holding_operation::tuple_holding_operation; | |
192 | ||
193 | value *evaluate (struct type *expect_type, | |
194 | struct expression *exp, | |
195 | enum noside noside) override; | |
196 | ||
197 | enum exp_opcode opcode () const override | |
198 | { return TERNOP_IN_RANGE; } | |
199 | }; | |
200 | ||
7c15d377 TT |
201 | using ada_neg_operation = unop_operation<UNOP_NEG, ada_unop_neg>; |
202 | using ada_atr_tag_operation = unop_operation<OP_ATR_TAG, ada_atr_tag>; | |
203 | using ada_atr_size_operation = unop_operation<OP_ATR_SIZE, ada_atr_size>; | |
204 | using ada_abs_operation = unop_operation<UNOP_ABS, ada_abs>; | |
7631cf6c | 205 | using ada_pos_operation = unop_operation<OP_ATR_POS, ada_pos_atr>; |
7c15d377 | 206 | |
95d49dfb TT |
207 | /* The in-range operation, given a type. */ |
208 | class ada_unop_range_operation | |
209 | : public tuple_holding_operation<operation_up, struct type *> | |
210 | { | |
211 | public: | |
212 | ||
213 | using tuple_holding_operation::tuple_holding_operation; | |
214 | ||
215 | value *evaluate (struct type *expect_type, | |
216 | struct expression *exp, | |
217 | enum noside noside) override | |
218 | { | |
219 | value *val = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); | |
220 | return ada_unop_in_range (expect_type, exp, noside, UNOP_IN_RANGE, | |
221 | val, std::get<1> (m_storage)); | |
222 | } | |
223 | ||
224 | enum exp_opcode opcode () const override | |
225 | { return UNOP_IN_RANGE; } | |
226 | }; | |
227 | ||
73796c73 TT |
228 | /* The Ada + and - operators. */ |
229 | class ada_binop_addsub_operation | |
230 | : public tuple_holding_operation<enum exp_opcode, operation_up, operation_up> | |
231 | { | |
232 | public: | |
233 | ||
234 | using tuple_holding_operation::tuple_holding_operation; | |
235 | ||
236 | value *evaluate (struct type *expect_type, | |
237 | struct expression *exp, | |
238 | enum noside noside) override; | |
239 | ||
240 | enum exp_opcode opcode () const override | |
241 | { return std::get<0> (m_storage); } | |
242 | }; | |
243 | ||
d9e7db06 TT |
244 | using ada_binop_mul_operation = binop_operation<BINOP_MUL, ada_mult_binop>; |
245 | using ada_binop_div_operation = binop_operation<BINOP_DIV, ada_mult_binop>; | |
246 | using ada_binop_rem_operation = binop_operation<BINOP_REM, ada_mult_binop>; | |
247 | using ada_binop_mod_operation = binop_operation<BINOP_MOD, ada_mult_binop>; | |
248 | ||
0922dc84 TT |
249 | using ada_binop_min_operation = binop_operation<BINOP_MIN, ada_binop_minmax>; |
250 | using ada_binop_max_operation = binop_operation<BINOP_MAX, ada_binop_minmax>; | |
6ad3b8bf | 251 | |
065ec826 TT |
252 | using ada_binop_exp_operation = binop_operation<BINOP_EXP, ada_binop_exp>; |
253 | ||
6e8fb7b7 TT |
254 | /* Implement the equal and not-equal operations for Ada. */ |
255 | class ada_binop_equal_operation | |
256 | : public tuple_holding_operation<enum exp_opcode, operation_up, operation_up> | |
257 | { | |
258 | public: | |
259 | ||
260 | using tuple_holding_operation::tuple_holding_operation; | |
261 | ||
262 | value *evaluate (struct type *expect_type, | |
263 | struct expression *exp, | |
264 | enum noside noside) override | |
265 | { | |
266 | value *arg1 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); | |
d0c97917 | 267 | value *arg2 = std::get<2> (m_storage)->evaluate (arg1->type (), |
6e8fb7b7 TT |
268 | exp, noside); |
269 | return ada_equal_binop (expect_type, exp, noside, std::get<0> (m_storage), | |
270 | arg1, arg2); | |
271 | } | |
272 | ||
013a623f TT |
273 | void do_generate_ax (struct expression *exp, |
274 | struct agent_expr *ax, | |
275 | struct axs_value *value, | |
276 | struct type *cast_type) | |
277 | override | |
278 | { | |
279 | gen_expr_binop (exp, opcode (), | |
280 | std::get<1> (this->m_storage).get (), | |
281 | std::get<2> (this->m_storage).get (), | |
282 | ax, value); | |
283 | } | |
284 | ||
6e8fb7b7 TT |
285 | enum exp_opcode opcode () const override |
286 | { return std::get<0> (m_storage); } | |
287 | }; | |
288 | ||
039e4b76 TT |
289 | /* Bitwise operators for Ada. */ |
290 | template<enum exp_opcode OP> | |
291 | class ada_bitwise_operation | |
292 | : public maybe_constant_operation<operation_up, operation_up> | |
293 | { | |
294 | public: | |
295 | ||
296 | using maybe_constant_operation::maybe_constant_operation; | |
297 | ||
298 | value *evaluate (struct type *expect_type, | |
299 | struct expression *exp, | |
300 | enum noside noside) override | |
301 | { | |
302 | value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); | |
303 | value *rhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); | |
304 | value *result = eval_op_binary (expect_type, exp, noside, OP, lhs, rhs); | |
d0c97917 | 305 | return value_cast (lhs->type (), result); |
039e4b76 TT |
306 | } |
307 | ||
308 | enum exp_opcode opcode () const override | |
309 | { return OP; } | |
310 | }; | |
311 | ||
312 | using ada_bitwise_and_operation = ada_bitwise_operation<BINOP_BITWISE_AND>; | |
313 | using ada_bitwise_ior_operation = ada_bitwise_operation<BINOP_BITWISE_IOR>; | |
314 | using ada_bitwise_xor_operation = ada_bitwise_operation<BINOP_BITWISE_XOR>; | |
315 | ||
1b1ebfab TT |
316 | /* Ada array- or string-slice operation. */ |
317 | class ada_ternop_slice_operation | |
d8a4ed8a TT |
318 | : public maybe_constant_operation<operation_up, operation_up, operation_up>, |
319 | public ada_resolvable | |
1b1ebfab TT |
320 | { |
321 | public: | |
322 | ||
323 | using maybe_constant_operation::maybe_constant_operation; | |
324 | ||
325 | value *evaluate (struct type *expect_type, | |
326 | struct expression *exp, | |
327 | enum noside noside) override | |
328 | { | |
329 | value *array = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); | |
330 | value *low = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); | |
331 | value *high = std::get<2> (m_storage)->evaluate (nullptr, exp, noside); | |
332 | return ada_ternop_slice (exp, noside, array, low, high); | |
333 | } | |
334 | ||
335 | enum exp_opcode opcode () const override | |
336 | { return TERNOP_SLICE; } | |
d8a4ed8a TT |
337 | |
338 | bool resolve (struct expression *exp, | |
339 | bool deprocedure_p, | |
340 | bool parse_completion, | |
341 | innermost_block_tracker *tracker, | |
342 | struct type *context_type) override; | |
1b1ebfab TT |
343 | }; |
344 | ||
82c3886e TT |
345 | /* Implement BINOP_IN_BOUNDS for Ada. */ |
346 | class ada_binop_in_bounds_operation | |
347 | : public maybe_constant_operation<operation_up, operation_up, int> | |
348 | { | |
349 | public: | |
350 | ||
351 | using maybe_constant_operation::maybe_constant_operation; | |
352 | ||
353 | value *evaluate (struct type *expect_type, | |
354 | struct expression *exp, | |
355 | enum noside noside) override | |
356 | { | |
357 | value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); | |
358 | value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); | |
359 | return ada_binop_in_bounds (exp, noside, arg1, arg2, | |
360 | std::get<2> (m_storage)); | |
361 | } | |
362 | ||
363 | enum exp_opcode opcode () const override | |
364 | { return BINOP_IN_BOUNDS; } | |
365 | }; | |
366 | ||
60fa02ca TT |
367 | /* Implement several unary Ada OP_ATR_* operations. */ |
368 | class ada_unop_atr_operation | |
369 | : public maybe_constant_operation<operation_up, enum exp_opcode, int> | |
370 | { | |
371 | public: | |
372 | ||
373 | using maybe_constant_operation::maybe_constant_operation; | |
374 | ||
375 | value *evaluate (struct type *expect_type, | |
376 | struct expression *exp, | |
377 | enum noside noside) override; | |
378 | ||
379 | enum exp_opcode opcode () const override | |
380 | { return std::get<1> (m_storage); } | |
381 | }; | |
382 | ||
99a3b1e7 TT |
383 | /* Variant of var_value_operation for Ada. */ |
384 | class ada_var_value_operation | |
d8a4ed8a | 385 | : public var_value_operation, public ada_resolvable |
99a3b1e7 TT |
386 | { |
387 | public: | |
388 | ||
389 | using var_value_operation::var_value_operation; | |
390 | ||
391 | value *evaluate (struct type *expect_type, | |
392 | struct expression *exp, | |
393 | enum noside noside) override; | |
394 | ||
395 | value *evaluate_for_cast (struct type *expect_type, | |
396 | struct expression *exp, | |
397 | enum noside noside) override; | |
398 | ||
d8a4ed8a | 399 | const block *get_block () const |
9e5e03df | 400 | { return std::get<0> (m_storage).block; } |
d8a4ed8a TT |
401 | |
402 | bool resolve (struct expression *exp, | |
403 | bool deprocedure_p, | |
404 | bool parse_completion, | |
405 | innermost_block_tracker *tracker, | |
406 | struct type *context_type) override; | |
407 | ||
99a3b1e7 TT |
408 | protected: |
409 | ||
013a623f TT |
410 | void do_generate_ax (struct expression *exp, |
411 | struct agent_expr *ax, | |
412 | struct axs_value *value, | |
413 | struct type *cast_type) | |
414 | override; | |
99a3b1e7 TT |
415 | }; |
416 | ||
3f4a0053 TT |
417 | /* Variant of var_msym_value_operation for Ada. */ |
418 | class ada_var_msym_value_operation | |
419 | : public var_msym_value_operation | |
420 | { | |
421 | public: | |
422 | ||
423 | using var_msym_value_operation::var_msym_value_operation; | |
424 | ||
425 | value *evaluate_for_cast (struct type *expect_type, | |
426 | struct expression *exp, | |
427 | enum noside noside) override; | |
428 | ||
429 | protected: | |
430 | ||
431 | using operation::do_generate_ax; | |
432 | }; | |
433 | ||
22f6f797 TT |
434 | typedef struct value *ada_atr_ftype (struct expression *exp, |
435 | enum noside noside, | |
436 | struct type *type, | |
437 | struct value *arg); | |
438 | ||
439 | /* Implement several Ada attributes. */ | |
440 | template<ada_atr_ftype FUNC> | |
441 | class ada_atr_operation | |
9e99f48f TT |
442 | : public tuple_holding_operation<struct type *, operation_up> |
443 | { | |
444 | public: | |
445 | ||
446 | using tuple_holding_operation::tuple_holding_operation; | |
447 | ||
448 | value *evaluate (struct type *expect_type, | |
449 | struct expression *exp, | |
22f6f797 TT |
450 | enum noside noside) override |
451 | { | |
452 | value *arg = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); | |
453 | return FUNC (exp, noside, std::get<0> (m_storage), arg); | |
454 | } | |
9e99f48f TT |
455 | |
456 | enum exp_opcode opcode () const override | |
22f6f797 TT |
457 | { |
458 | /* The value here generally doesn't matter. */ | |
459 | return OP_ATR_VAL; | |
460 | } | |
9e99f48f TT |
461 | }; |
462 | ||
22f6f797 TT |
463 | using ada_atr_val_operation = ada_atr_operation<ada_val_atr>; |
464 | using ada_atr_enum_rep_operation = ada_atr_operation<ada_atr_enum_rep>; | |
465 | using ada_atr_enum_val_operation = ada_atr_operation<ada_atr_enum_val>; | |
466 | ||
e8c33fa1 TT |
467 | /* The indirection operator for Ada. */ |
468 | class ada_unop_ind_operation | |
469 | : public unop_ind_base_operation | |
470 | { | |
471 | public: | |
472 | ||
473 | using unop_ind_base_operation::unop_ind_base_operation; | |
474 | ||
475 | value *evaluate (struct type *expect_type, | |
476 | struct expression *exp, | |
477 | enum noside noside) override; | |
478 | }; | |
479 | ||
ebc06ad8 TT |
480 | /* Implement STRUCTOP_STRUCT for Ada. */ |
481 | class ada_structop_operation | |
482 | : public structop_base_operation | |
483 | { | |
484 | public: | |
485 | ||
486 | using structop_base_operation::structop_base_operation; | |
487 | ||
488 | value *evaluate (struct type *expect_type, | |
489 | struct expression *exp, | |
490 | enum noside noside) override; | |
491 | ||
492 | enum exp_opcode opcode () const override | |
493 | { return STRUCTOP_STRUCT; } | |
d4da1b2c TT |
494 | |
495 | /* Set the completion prefix. */ | |
496 | void set_prefix (std::string &&prefix) | |
497 | { | |
498 | m_prefix = std::move (prefix); | |
499 | } | |
500 | ||
501 | bool complete (struct expression *exp, completion_tracker &tracker) override | |
502 | { | |
503 | return structop_base_operation::complete (exp, tracker, m_prefix.c_str ()); | |
504 | } | |
505 | ||
506 | void dump (struct ui_file *stream, int depth) const override | |
507 | { | |
508 | structop_base_operation::dump (stream, depth); | |
509 | dump_for_expression (stream, depth + 1, m_prefix); | |
510 | } | |
511 | ||
512 | private: | |
513 | ||
514 | /* We may need to provide a prefix to field name completion. See | |
515 | ada-exp.y:find_completion_bounds for details. */ | |
516 | std::string m_prefix; | |
ebc06ad8 TT |
517 | }; |
518 | ||
efe3af2f TT |
519 | /* Function calls for Ada. */ |
520 | class ada_funcall_operation | |
d8a4ed8a TT |
521 | : public tuple_holding_operation<operation_up, std::vector<operation_up>>, |
522 | public ada_resolvable | |
efe3af2f TT |
523 | { |
524 | public: | |
525 | ||
526 | using tuple_holding_operation::tuple_holding_operation; | |
527 | ||
528 | value *evaluate (struct type *expect_type, | |
529 | struct expression *exp, | |
530 | enum noside noside) override; | |
531 | ||
d8a4ed8a TT |
532 | bool resolve (struct expression *exp, |
533 | bool deprocedure_p, | |
534 | bool parse_completion, | |
535 | innermost_block_tracker *tracker, | |
536 | struct type *context_type) override; | |
537 | ||
efe3af2f TT |
538 | enum exp_opcode opcode () const override |
539 | { return OP_FUNCALL; } | |
540 | }; | |
541 | ||
a88c4354 TT |
542 | /* An Ada assignment operation. */ |
543 | class ada_assign_operation | |
544 | : public assign_operation | |
545 | { | |
546 | public: | |
547 | ||
548 | using assign_operation::assign_operation; | |
549 | ||
550 | value *evaluate (struct type *expect_type, | |
551 | struct expression *exp, | |
552 | enum noside noside) override; | |
553 | ||
554 | enum exp_opcode opcode () const override | |
555 | { return BINOP_ASSIGN; } | |
b3a27d2f TT |
556 | |
557 | value *current () | |
558 | { return m_current; } | |
559 | ||
560 | /* A helper function for the parser to evaluate just the LHS of the | |
561 | assignment. */ | |
562 | value *eval_for_resolution (struct expression *exp) | |
563 | { | |
564 | return std::get<0> (m_storage)->evaluate (nullptr, exp, | |
565 | EVAL_AVOID_SIDE_EFFECTS); | |
566 | } | |
567 | ||
568 | /* The parser must construct the assignment node before parsing the | |
569 | RHS, so that '@' can access the assignment, so this helper | |
570 | function is needed to set the RHS after construction. */ | |
571 | void set_rhs (operation_up rhs) | |
572 | { | |
573 | std::get<1> (m_storage) = std::move (rhs); | |
574 | } | |
575 | ||
576 | private: | |
577 | ||
578 | /* Temporary storage for the value of the left-hand-side. */ | |
579 | value *m_current = nullptr; | |
580 | }; | |
581 | ||
582 | /* Implement the Ada target name symbol ('@'). This is used to refer | |
583 | to the LHS of an assignment from the RHS. */ | |
584 | class ada_target_operation : public operation | |
585 | { | |
586 | public: | |
587 | ||
588 | explicit ada_target_operation (ada_assign_operation *lhs) | |
589 | : m_lhs (lhs) | |
590 | { } | |
591 | ||
592 | value *evaluate (struct type *expect_type, | |
593 | struct expression *exp, | |
594 | enum noside noside) override | |
595 | { | |
596 | if (noside == EVAL_AVOID_SIDE_EFFECTS) | |
597 | return m_lhs->eval_for_resolution (exp); | |
598 | return m_lhs->current (); | |
599 | } | |
600 | ||
601 | enum exp_opcode opcode () const override | |
602 | { | |
603 | /* It doesn't really matter. */ | |
604 | return OP_VAR_VALUE; | |
605 | } | |
606 | ||
607 | void dump (struct ui_file *stream, int depth) const override | |
608 | { | |
609 | gdb_printf (stream, _("%*sAda target symbol '@'\n"), depth, ""); | |
610 | } | |
611 | ||
612 | private: | |
613 | ||
614 | /* The left hand side of the assignment. */ | |
615 | ada_assign_operation *m_lhs; | |
a88c4354 TT |
616 | }; |
617 | ||
618 | /* This abstract class represents a single component in an Ada | |
619 | aggregate assignment. */ | |
620 | class ada_component | |
621 | { | |
622 | public: | |
623 | ||
624 | /* Assign to LHS, which is part of CONTAINER. EXP is the expression | |
625 | being evaluated. INDICES, LOW, and HIGH indicate which | |
626 | sub-components have already been assigned; INDICES should be | |
627 | updated by this call. */ | |
628 | virtual void assign (struct value *container, | |
629 | struct value *lhs, struct expression *exp, | |
630 | std::vector<LONGEST> &indices, | |
631 | LONGEST low, LONGEST high) = 0; | |
632 | ||
633 | /* Same as operation::uses_objfile. */ | |
634 | virtual bool uses_objfile (struct objfile *objfile) = 0; | |
635 | ||
636 | /* Same as operation::dump. */ | |
637 | virtual void dump (ui_file *stream, int depth) = 0; | |
638 | ||
639 | virtual ~ada_component () = default; | |
640 | ||
641 | protected: | |
642 | ||
643 | ada_component () = default; | |
644 | DISABLE_COPY_AND_ASSIGN (ada_component); | |
645 | }; | |
646 | ||
647 | /* Unique pointer specialization for Ada assignment components. */ | |
648 | typedef std::unique_ptr<ada_component> ada_component_up; | |
649 | ||
650 | /* An operation that holds a single component. */ | |
651 | class ada_aggregate_operation | |
652 | : public tuple_holding_operation<ada_component_up> | |
653 | { | |
654 | public: | |
655 | ||
656 | using tuple_holding_operation::tuple_holding_operation; | |
657 | ||
658 | /* Assuming that LHS represents an lvalue having a record or array | |
659 | type, evaluate an assignment of this aggregate's value to LHS. | |
660 | CONTAINER is an lvalue containing LHS (possibly LHS itself). | |
661 | Does not modify the inferior's memory, nor does it modify the | |
207582c0 TT |
662 | contents of LHS (unless == CONTAINER). Returns the modified |
663 | CONTAINER. */ | |
a88c4354 | 664 | |
207582c0 TT |
665 | value *assign_aggregate (struct value *container, |
666 | struct value *lhs, | |
667 | struct expression *exp); | |
a88c4354 TT |
668 | |
669 | value *evaluate (struct type *expect_type, | |
670 | struct expression *exp, | |
671 | enum noside noside) override | |
672 | { | |
673 | error (_("Aggregates only allowed on the right of an assignment")); | |
674 | } | |
675 | ||
676 | enum exp_opcode opcode () const override | |
677 | { return OP_AGGREGATE; } | |
678 | }; | |
679 | ||
680 | /* A component holding a vector of other components to assign. */ | |
681 | class ada_aggregate_component : public ada_component | |
682 | { | |
683 | public: | |
684 | ||
685 | explicit ada_aggregate_component (std::vector<ada_component_up> &&components) | |
686 | : m_components (std::move (components)) | |
687 | { | |
688 | } | |
689 | ||
690 | void assign (struct value *container, | |
691 | struct value *lhs, struct expression *exp, | |
692 | std::vector<LONGEST> &indices, | |
693 | LONGEST low, LONGEST high) override; | |
694 | ||
695 | bool uses_objfile (struct objfile *objfile) override; | |
696 | ||
697 | void dump (ui_file *stream, int depth) override; | |
698 | ||
699 | private: | |
700 | ||
701 | std::vector<ada_component_up> m_components; | |
702 | }; | |
703 | ||
704 | /* A component that assigns according to a provided index (which is | |
705 | relative to the "low" value). */ | |
706 | class ada_positional_component : public ada_component | |
707 | { | |
708 | public: | |
709 | ||
710 | ada_positional_component (int index, operation_up &&op) | |
711 | : m_index (index), | |
712 | m_op (std::move (op)) | |
713 | { | |
714 | } | |
715 | ||
716 | void assign (struct value *container, | |
717 | struct value *lhs, struct expression *exp, | |
718 | std::vector<LONGEST> &indices, | |
719 | LONGEST low, LONGEST high) override; | |
720 | ||
721 | bool uses_objfile (struct objfile *objfile) override; | |
722 | ||
723 | void dump (ui_file *stream, int depth) override; | |
724 | ||
725 | private: | |
726 | ||
727 | int m_index; | |
728 | operation_up m_op; | |
729 | }; | |
730 | ||
731 | /* A component which handles an "others" clause. */ | |
732 | class ada_others_component : public ada_component | |
733 | { | |
734 | public: | |
735 | ||
736 | explicit ada_others_component (operation_up &&op) | |
737 | : m_op (std::move (op)) | |
738 | { | |
739 | } | |
740 | ||
741 | void assign (struct value *container, | |
742 | struct value *lhs, struct expression *exp, | |
743 | std::vector<LONGEST> &indices, | |
744 | LONGEST low, LONGEST high) override; | |
745 | ||
746 | bool uses_objfile (struct objfile *objfile) override; | |
747 | ||
748 | void dump (ui_file *stream, int depth) override; | |
749 | ||
750 | private: | |
751 | ||
752 | operation_up m_op; | |
753 | }; | |
754 | ||
755 | /* An interface that represents an association that is used in | |
756 | aggregate assignment. */ | |
757 | class ada_association | |
758 | { | |
759 | public: | |
760 | ||
761 | /* Like ada_component::assign, but takes an operation as a | |
762 | parameter. The operation is evaluated and then assigned into LHS | |
763 | according to the rules of the concrete implementation. */ | |
764 | virtual void assign (struct value *container, | |
765 | struct value *lhs, | |
766 | struct expression *exp, | |
767 | std::vector<LONGEST> &indices, | |
768 | LONGEST low, LONGEST high, | |
769 | operation_up &op) = 0; | |
770 | ||
771 | /* Same as operation::uses_objfile. */ | |
772 | virtual bool uses_objfile (struct objfile *objfile) = 0; | |
773 | ||
774 | /* Same as operation::dump. */ | |
775 | virtual void dump (ui_file *stream, int depth) = 0; | |
776 | ||
777 | virtual ~ada_association () = default; | |
778 | ||
779 | protected: | |
780 | ||
781 | ada_association () = default; | |
782 | DISABLE_COPY_AND_ASSIGN (ada_association); | |
783 | }; | |
784 | ||
785 | /* Unique pointer specialization for Ada assignment associations. */ | |
786 | typedef std::unique_ptr<ada_association> ada_association_up; | |
787 | ||
788 | /* A component that holds a vector of associations and an operation. | |
789 | The operation is re-evaluated for each choice. */ | |
790 | class ada_choices_component : public ada_component | |
791 | { | |
792 | public: | |
793 | ||
794 | explicit ada_choices_component (operation_up &&op) | |
795 | : m_op (std::move (op)) | |
796 | { | |
797 | } | |
798 | ||
799 | /* Set the vector of associations. This is done separately from the | |
800 | constructor because it was simpler for the implementation of the | |
801 | parser. */ | |
802 | void set_associations (std::vector<ada_association_up> &&assoc) | |
803 | { | |
804 | m_assocs = std::move (assoc); | |
805 | } | |
806 | ||
807 | void assign (struct value *container, | |
808 | struct value *lhs, struct expression *exp, | |
809 | std::vector<LONGEST> &indices, | |
810 | LONGEST low, LONGEST high) override; | |
811 | ||
812 | bool uses_objfile (struct objfile *objfile) override; | |
813 | ||
814 | void dump (ui_file *stream, int depth) override; | |
815 | ||
816 | private: | |
817 | ||
818 | std::vector<ada_association_up> m_assocs; | |
819 | operation_up m_op; | |
820 | }; | |
821 | ||
822 | /* An association that uses a discrete range. */ | |
823 | class ada_discrete_range_association : public ada_association | |
824 | { | |
825 | public: | |
826 | ||
827 | ada_discrete_range_association (operation_up &&low, operation_up &&high) | |
828 | : m_low (std::move (low)), | |
829 | m_high (std::move (high)) | |
830 | { | |
831 | } | |
832 | ||
833 | void assign (struct value *container, | |
834 | struct value *lhs, struct expression *exp, | |
835 | std::vector<LONGEST> &indices, | |
836 | LONGEST low, LONGEST high, | |
837 | operation_up &op) override; | |
838 | ||
839 | bool uses_objfile (struct objfile *objfile) override; | |
840 | ||
841 | void dump (ui_file *stream, int depth) override; | |
842 | ||
843 | private: | |
844 | ||
845 | operation_up m_low; | |
846 | operation_up m_high; | |
847 | }; | |
848 | ||
849 | /* An association that uses a name. The name may be an expression | |
850 | that evaluates to an integer (for arrays), or an Ada string or | |
851 | variable value operation. */ | |
852 | class ada_name_association : public ada_association | |
853 | { | |
854 | public: | |
855 | ||
856 | explicit ada_name_association (operation_up val) | |
857 | : m_val (std::move (val)) | |
858 | { | |
859 | } | |
860 | ||
861 | void assign (struct value *container, | |
862 | struct value *lhs, struct expression *exp, | |
863 | std::vector<LONGEST> &indices, | |
864 | LONGEST low, LONGEST high, | |
865 | operation_up &op) override; | |
866 | ||
867 | bool uses_objfile (struct objfile *objfile) override; | |
868 | ||
869 | void dump (ui_file *stream, int depth) override; | |
870 | ||
871 | private: | |
872 | ||
873 | operation_up m_val; | |
874 | }; | |
875 | ||
03adb248 TT |
876 | /* A character constant expression. This is a separate operation so |
877 | that it can participate in resolution, so that TYPE'(CST) can | |
878 | work correctly for enums with character enumerators. */ | |
879 | class ada_char_operation : public long_const_operation, | |
880 | public ada_resolvable | |
881 | { | |
882 | public: | |
883 | ||
884 | using long_const_operation::long_const_operation; | |
885 | ||
886 | bool resolve (struct expression *exp, | |
887 | bool deprocedure_p, | |
888 | bool parse_completion, | |
889 | innermost_block_tracker *tracker, | |
890 | struct type *context_type) override | |
891 | { | |
892 | /* This should never be called, because this class also implements | |
893 | 'replace'. */ | |
894 | gdb_assert_not_reached ("unexpected call"); | |
895 | } | |
896 | ||
897 | operation_up replace (operation_up &&owner, | |
898 | struct expression *exp, | |
899 | bool deprocedure_p, | |
900 | bool parse_completion, | |
901 | innermost_block_tracker *tracker, | |
902 | struct type *context_type) override; | |
b1b9c411 TT |
903 | |
904 | value *evaluate (struct type *expect_type, | |
905 | struct expression *exp, | |
906 | enum noside noside) override; | |
907 | }; | |
908 | ||
909 | class ada_concat_operation : public concat_operation | |
910 | { | |
911 | public: | |
912 | ||
913 | using concat_operation::concat_operation; | |
914 | ||
915 | value *evaluate (struct type *expect_type, | |
916 | struct expression *exp, | |
917 | enum noside noside) override; | |
03adb248 TT |
918 | }; |
919 | ||
03070ee9 TT |
920 | } /* namespace expr */ |
921 | ||
922 | #endif /* ADA_EXP_H */ |