Implement Ada assignment
[deliverable/binutils-gdb.git] / gdb / ada-exp.h
1 /* Definitions for Ada 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 ADA_EXP_H
21 #define ADA_EXP_H
22
23 #include "expop.h"
24
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);
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);
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);
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);
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);
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);
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);
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);
72 extern struct value *ada_val_atr (enum noside noside, struct type *type,
73 struct value *arg);
74 extern struct value *ada_binop_exp (struct type *expect_type,
75 struct expression *exp,
76 enum noside noside, enum exp_opcode op,
77 struct value *arg1, struct value *arg2);
78
79 namespace expr
80 {
81
82 /* The base class for Ada type resolution. Ada operations that want
83 to participate in resolution implement this interface. */
84 struct ada_resolvable
85 {
86 /* Resolve this object. EXP is the expression being resolved.
87 DEPROCEDURE_P is true if a symbol that refers to a zero-argument
88 function may be turned into a function call. PARSE_COMPLETION
89 and TRACKER are passed in from the parser context. CONTEXT_TYPE
90 is the expected type of the expression, or nullptr if none is
91 known. This method should return true if the operation should be
92 replaced by a function call with this object as the callee. */
93 virtual bool resolve (struct expression *exp,
94 bool deprocedure_p,
95 bool parse_completion,
96 innermost_block_tracker *tracker,
97 struct type *context_type) = 0;
98 };
99
100 /* In Ada, some generic operations must be wrapped with a handler that
101 handles some Ada-specific type conversions. */
102 class ada_wrapped_operation
103 : public tuple_holding_operation<operation_up>
104 {
105 public:
106
107 using tuple_holding_operation::tuple_holding_operation;
108
109 value *evaluate (struct type *expect_type,
110 struct expression *exp,
111 enum noside noside) override;
112
113 enum exp_opcode opcode () const override
114 { return std::get<0> (m_storage)->opcode (); }
115 };
116
117 /* An Ada string constant. */
118 class ada_string_operation
119 : public string_operation
120 {
121 public:
122
123 using string_operation::string_operation;
124
125 /* Return the underlying string. */
126 const char *get_name () const
127 {
128 return std::get<0> (m_storage).c_str ();
129 }
130
131 value *evaluate (struct type *expect_type,
132 struct expression *exp,
133 enum noside noside) override;
134 };
135
136 /* The Ada TYPE'(EXP) construct. */
137 class ada_qual_operation
138 : public tuple_holding_operation<operation_up, struct type *>
139 {
140 public:
141
142 using tuple_holding_operation::tuple_holding_operation;
143
144 value *evaluate (struct type *expect_type,
145 struct expression *exp,
146 enum noside noside) override;
147
148 enum exp_opcode opcode () const override
149 { return UNOP_QUAL; }
150 };
151
152 /* Ternary in-range operator. */
153 class ada_ternop_range_operation
154 : public tuple_holding_operation<operation_up, operation_up, operation_up>
155 {
156 public:
157
158 using tuple_holding_operation::tuple_holding_operation;
159
160 value *evaluate (struct type *expect_type,
161 struct expression *exp,
162 enum noside noside) override;
163
164 enum exp_opcode opcode () const override
165 { return TERNOP_IN_RANGE; }
166 };
167
168 using ada_neg_operation = unop_operation<UNOP_NEG, ada_unop_neg>;
169 using ada_atr_tag_operation = unop_operation<OP_ATR_TAG, ada_atr_tag>;
170 using ada_atr_size_operation = unop_operation<OP_ATR_SIZE, ada_atr_size>;
171 using ada_abs_operation = unop_operation<UNOP_ABS, ada_abs>;
172 using ada_pos_operation = unop_operation<OP_ATR_POS, ada_pos_atr>;
173
174 /* The in-range operation, given a type. */
175 class ada_unop_range_operation
176 : public tuple_holding_operation<operation_up, struct type *>
177 {
178 public:
179
180 using tuple_holding_operation::tuple_holding_operation;
181
182 value *evaluate (struct type *expect_type,
183 struct expression *exp,
184 enum noside noside) override
185 {
186 value *val = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
187 return ada_unop_in_range (expect_type, exp, noside, UNOP_IN_RANGE,
188 val, std::get<1> (m_storage));
189 }
190
191 enum exp_opcode opcode () const override
192 { return UNOP_IN_RANGE; }
193 };
194
195 /* The Ada + and - operators. */
196 class ada_binop_addsub_operation
197 : public tuple_holding_operation<enum exp_opcode, operation_up, operation_up>
198 {
199 public:
200
201 using tuple_holding_operation::tuple_holding_operation;
202
203 value *evaluate (struct type *expect_type,
204 struct expression *exp,
205 enum noside noside) override;
206
207 enum exp_opcode opcode () const override
208 { return std::get<0> (m_storage); }
209 };
210
211 using ada_binop_mul_operation = binop_operation<BINOP_MUL, ada_mult_binop>;
212 using ada_binop_div_operation = binop_operation<BINOP_DIV, ada_mult_binop>;
213 using ada_binop_rem_operation = binop_operation<BINOP_REM, ada_mult_binop>;
214 using ada_binop_mod_operation = binop_operation<BINOP_MOD, ada_mult_binop>;
215
216 using ada_binop_min_operation = binop_operation<OP_ATR_MIN, ada_binop_minmax>;
217 using ada_binop_max_operation = binop_operation<OP_ATR_MAX, ada_binop_minmax>;
218
219 using ada_binop_exp_operation = binop_operation<BINOP_EXP, ada_binop_exp>;
220
221 /* Implement the equal and not-equal operations for Ada. */
222 class ada_binop_equal_operation
223 : public tuple_holding_operation<enum exp_opcode, operation_up, operation_up>
224 {
225 public:
226
227 using tuple_holding_operation::tuple_holding_operation;
228
229 value *evaluate (struct type *expect_type,
230 struct expression *exp,
231 enum noside noside) override
232 {
233 value *arg1 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
234 value *arg2 = std::get<2> (m_storage)->evaluate (value_type (arg1),
235 exp, noside);
236 return ada_equal_binop (expect_type, exp, noside, std::get<0> (m_storage),
237 arg1, arg2);
238 }
239
240 enum exp_opcode opcode () const override
241 { return std::get<0> (m_storage); }
242 };
243
244 /* Bitwise operators for Ada. */
245 template<enum exp_opcode OP>
246 class ada_bitwise_operation
247 : public maybe_constant_operation<operation_up, operation_up>
248 {
249 public:
250
251 using maybe_constant_operation::maybe_constant_operation;
252
253 value *evaluate (struct type *expect_type,
254 struct expression *exp,
255 enum noside noside) override
256 {
257 value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
258 value *rhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
259 value *result = eval_op_binary (expect_type, exp, noside, OP, lhs, rhs);
260 return value_cast (value_type (lhs), result);
261 }
262
263 enum exp_opcode opcode () const override
264 { return OP; }
265 };
266
267 using ada_bitwise_and_operation = ada_bitwise_operation<BINOP_BITWISE_AND>;
268 using ada_bitwise_ior_operation = ada_bitwise_operation<BINOP_BITWISE_IOR>;
269 using ada_bitwise_xor_operation = ada_bitwise_operation<BINOP_BITWISE_XOR>;
270
271 /* Ada array- or string-slice operation. */
272 class ada_ternop_slice_operation
273 : public maybe_constant_operation<operation_up, operation_up, operation_up>,
274 public ada_resolvable
275 {
276 public:
277
278 using maybe_constant_operation::maybe_constant_operation;
279
280 value *evaluate (struct type *expect_type,
281 struct expression *exp,
282 enum noside noside) override
283 {
284 value *array = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
285 value *low = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
286 value *high = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
287 return ada_ternop_slice (exp, noside, array, low, high);
288 }
289
290 enum exp_opcode opcode () const override
291 { return TERNOP_SLICE; }
292
293 bool resolve (struct expression *exp,
294 bool deprocedure_p,
295 bool parse_completion,
296 innermost_block_tracker *tracker,
297 struct type *context_type) override;
298 };
299
300 /* Implement BINOP_IN_BOUNDS for Ada. */
301 class ada_binop_in_bounds_operation
302 : public maybe_constant_operation<operation_up, operation_up, int>
303 {
304 public:
305
306 using maybe_constant_operation::maybe_constant_operation;
307
308 value *evaluate (struct type *expect_type,
309 struct expression *exp,
310 enum noside noside) override
311 {
312 value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
313 value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
314 return ada_binop_in_bounds (exp, noside, arg1, arg2,
315 std::get<2> (m_storage));
316 }
317
318 enum exp_opcode opcode () const override
319 { return BINOP_IN_BOUNDS; }
320 };
321
322 /* Implement several unary Ada OP_ATR_* operations. */
323 class ada_unop_atr_operation
324 : public maybe_constant_operation<operation_up, enum exp_opcode, int>
325 {
326 public:
327
328 using maybe_constant_operation::maybe_constant_operation;
329
330 value *evaluate (struct type *expect_type,
331 struct expression *exp,
332 enum noside noside) override;
333
334 enum exp_opcode opcode () const override
335 { return std::get<1> (m_storage); }
336 };
337
338 /* Variant of var_value_operation for Ada. */
339 class ada_var_value_operation
340 : public var_value_operation, public ada_resolvable
341 {
342 public:
343
344 using var_value_operation::var_value_operation;
345
346 value *evaluate (struct type *expect_type,
347 struct expression *exp,
348 enum noside noside) override;
349
350 value *evaluate_for_cast (struct type *expect_type,
351 struct expression *exp,
352 enum noside noside) override;
353
354 symbol *get_symbol () const
355 { return std::get<0> (m_storage); }
356
357 const block *get_block () const
358 { return std::get<1> (m_storage); }
359
360 bool resolve (struct expression *exp,
361 bool deprocedure_p,
362 bool parse_completion,
363 innermost_block_tracker *tracker,
364 struct type *context_type) override;
365
366 protected:
367
368 using operation::do_generate_ax;
369 };
370
371 /* Variant of var_msym_value_operation for Ada. */
372 class ada_var_msym_value_operation
373 : public var_msym_value_operation
374 {
375 public:
376
377 using var_msym_value_operation::var_msym_value_operation;
378
379 value *evaluate_for_cast (struct type *expect_type,
380 struct expression *exp,
381 enum noside noside) override;
382
383 protected:
384
385 using operation::do_generate_ax;
386 };
387
388 /* Implement the Ada 'val attribute. */
389 class ada_atr_val_operation
390 : public tuple_holding_operation<struct type *, operation_up>
391 {
392 public:
393
394 using tuple_holding_operation::tuple_holding_operation;
395
396 value *evaluate (struct type *expect_type,
397 struct expression *exp,
398 enum noside noside) override;
399
400 enum exp_opcode opcode () const override
401 { return OP_ATR_VAL; }
402 };
403
404 /* The indirection operator for Ada. */
405 class ada_unop_ind_operation
406 : public unop_ind_base_operation
407 {
408 public:
409
410 using unop_ind_base_operation::unop_ind_base_operation;
411
412 value *evaluate (struct type *expect_type,
413 struct expression *exp,
414 enum noside noside) override;
415 };
416
417 /* Implement STRUCTOP_STRUCT for Ada. */
418 class ada_structop_operation
419 : public structop_base_operation
420 {
421 public:
422
423 using structop_base_operation::structop_base_operation;
424
425 value *evaluate (struct type *expect_type,
426 struct expression *exp,
427 enum noside noside) override;
428
429 enum exp_opcode opcode () const override
430 { return STRUCTOP_STRUCT; }
431 };
432
433 /* Function calls for Ada. */
434 class ada_funcall_operation
435 : public tuple_holding_operation<operation_up, std::vector<operation_up>>,
436 public ada_resolvable
437 {
438 public:
439
440 using tuple_holding_operation::tuple_holding_operation;
441
442 value *evaluate (struct type *expect_type,
443 struct expression *exp,
444 enum noside noside) override;
445
446 bool resolve (struct expression *exp,
447 bool deprocedure_p,
448 bool parse_completion,
449 innermost_block_tracker *tracker,
450 struct type *context_type) override;
451
452 enum exp_opcode opcode () const override
453 { return OP_FUNCALL; }
454 };
455
456 /* An Ada assignment operation. */
457 class ada_assign_operation
458 : public assign_operation
459 {
460 public:
461
462 using assign_operation::assign_operation;
463
464 value *evaluate (struct type *expect_type,
465 struct expression *exp,
466 enum noside noside) override;
467
468 enum exp_opcode opcode () const override
469 { return BINOP_ASSIGN; }
470 };
471
472 /* This abstract class represents a single component in an Ada
473 aggregate assignment. */
474 class ada_component
475 {
476 public:
477
478 /* Assign to LHS, which is part of CONTAINER. EXP is the expression
479 being evaluated. INDICES, LOW, and HIGH indicate which
480 sub-components have already been assigned; INDICES should be
481 updated by this call. */
482 virtual void assign (struct value *container,
483 struct value *lhs, struct expression *exp,
484 std::vector<LONGEST> &indices,
485 LONGEST low, LONGEST high) = 0;
486
487 /* Same as operation::uses_objfile. */
488 virtual bool uses_objfile (struct objfile *objfile) = 0;
489
490 /* Same as operation::dump. */
491 virtual void dump (ui_file *stream, int depth) = 0;
492
493 virtual ~ada_component () = default;
494
495 protected:
496
497 ada_component () = default;
498 DISABLE_COPY_AND_ASSIGN (ada_component);
499 };
500
501 /* Unique pointer specialization for Ada assignment components. */
502 typedef std::unique_ptr<ada_component> ada_component_up;
503
504 /* An operation that holds a single component. */
505 class ada_aggregate_operation
506 : public tuple_holding_operation<ada_component_up>
507 {
508 public:
509
510 using tuple_holding_operation::tuple_holding_operation;
511
512 /* Assuming that LHS represents an lvalue having a record or array
513 type, evaluate an assignment of this aggregate's value to LHS.
514 CONTAINER is an lvalue containing LHS (possibly LHS itself).
515 Does not modify the inferior's memory, nor does it modify the
516 contents of LHS (unless == CONTAINER). */
517
518 void assign_aggregate (struct value *container,
519 struct value *lhs,
520 struct expression *exp);
521
522 value *evaluate (struct type *expect_type,
523 struct expression *exp,
524 enum noside noside) override
525 {
526 error (_("Aggregates only allowed on the right of an assignment"));
527 }
528
529 enum exp_opcode opcode () const override
530 { return OP_AGGREGATE; }
531 };
532
533 /* A component holding a vector of other components to assign. */
534 class ada_aggregate_component : public ada_component
535 {
536 public:
537
538 explicit ada_aggregate_component (std::vector<ada_component_up> &&components)
539 : m_components (std::move (components))
540 {
541 }
542
543 void assign (struct value *container,
544 struct value *lhs, struct expression *exp,
545 std::vector<LONGEST> &indices,
546 LONGEST low, LONGEST high) override;
547
548 bool uses_objfile (struct objfile *objfile) override;
549
550 void dump (ui_file *stream, int depth) override;
551
552 private:
553
554 std::vector<ada_component_up> m_components;
555 };
556
557 /* A component that assigns according to a provided index (which is
558 relative to the "low" value). */
559 class ada_positional_component : public ada_component
560 {
561 public:
562
563 ada_positional_component (int index, operation_up &&op)
564 : m_index (index),
565 m_op (std::move (op))
566 {
567 }
568
569 void assign (struct value *container,
570 struct value *lhs, struct expression *exp,
571 std::vector<LONGEST> &indices,
572 LONGEST low, LONGEST high) override;
573
574 bool uses_objfile (struct objfile *objfile) override;
575
576 void dump (ui_file *stream, int depth) override;
577
578 private:
579
580 int m_index;
581 operation_up m_op;
582 };
583
584 /* A component which handles an "others" clause. */
585 class ada_others_component : public ada_component
586 {
587 public:
588
589 explicit ada_others_component (operation_up &&op)
590 : m_op (std::move (op))
591 {
592 }
593
594 void assign (struct value *container,
595 struct value *lhs, struct expression *exp,
596 std::vector<LONGEST> &indices,
597 LONGEST low, LONGEST high) override;
598
599 bool uses_objfile (struct objfile *objfile) override;
600
601 void dump (ui_file *stream, int depth) override;
602
603 private:
604
605 operation_up m_op;
606 };
607
608 /* An interface that represents an association that is used in
609 aggregate assignment. */
610 class ada_association
611 {
612 public:
613
614 /* Like ada_component::assign, but takes an operation as a
615 parameter. The operation is evaluated and then assigned into LHS
616 according to the rules of the concrete implementation. */
617 virtual void assign (struct value *container,
618 struct value *lhs,
619 struct expression *exp,
620 std::vector<LONGEST> &indices,
621 LONGEST low, LONGEST high,
622 operation_up &op) = 0;
623
624 /* Same as operation::uses_objfile. */
625 virtual bool uses_objfile (struct objfile *objfile) = 0;
626
627 /* Same as operation::dump. */
628 virtual void dump (ui_file *stream, int depth) = 0;
629
630 virtual ~ada_association () = default;
631
632 protected:
633
634 ada_association () = default;
635 DISABLE_COPY_AND_ASSIGN (ada_association);
636 };
637
638 /* Unique pointer specialization for Ada assignment associations. */
639 typedef std::unique_ptr<ada_association> ada_association_up;
640
641 /* A component that holds a vector of associations and an operation.
642 The operation is re-evaluated for each choice. */
643 class ada_choices_component : public ada_component
644 {
645 public:
646
647 explicit ada_choices_component (operation_up &&op)
648 : m_op (std::move (op))
649 {
650 }
651
652 /* Set the vector of associations. This is done separately from the
653 constructor because it was simpler for the implementation of the
654 parser. */
655 void set_associations (std::vector<ada_association_up> &&assoc)
656 {
657 m_assocs = std::move (assoc);
658 }
659
660 void assign (struct value *container,
661 struct value *lhs, struct expression *exp,
662 std::vector<LONGEST> &indices,
663 LONGEST low, LONGEST high) override;
664
665 bool uses_objfile (struct objfile *objfile) override;
666
667 void dump (ui_file *stream, int depth) override;
668
669 private:
670
671 std::vector<ada_association_up> m_assocs;
672 operation_up m_op;
673 };
674
675 /* An association that uses a discrete range. */
676 class ada_discrete_range_association : public ada_association
677 {
678 public:
679
680 ada_discrete_range_association (operation_up &&low, operation_up &&high)
681 : m_low (std::move (low)),
682 m_high (std::move (high))
683 {
684 }
685
686 void assign (struct value *container,
687 struct value *lhs, struct expression *exp,
688 std::vector<LONGEST> &indices,
689 LONGEST low, LONGEST high,
690 operation_up &op) override;
691
692 bool uses_objfile (struct objfile *objfile) override;
693
694 void dump (ui_file *stream, int depth) override;
695
696 private:
697
698 operation_up m_low;
699 operation_up m_high;
700 };
701
702 /* An association that uses a name. The name may be an expression
703 that evaluates to an integer (for arrays), or an Ada string or
704 variable value operation. */
705 class ada_name_association : public ada_association
706 {
707 public:
708
709 explicit ada_name_association (operation_up val)
710 : m_val (std::move (val))
711 {
712 }
713
714 void assign (struct value *container,
715 struct value *lhs, struct expression *exp,
716 std::vector<LONGEST> &indices,
717 LONGEST low, LONGEST high,
718 operation_up &op) override;
719
720 bool uses_objfile (struct objfile *objfile) override;
721
722 void dump (ui_file *stream, int depth) override;
723
724 private:
725
726 operation_up m_val;
727 };
728
729 } /* namespace expr */
730
731 #endif /* ADA_EXP_H */
This page took 0.044296 seconds and 5 git commands to generate.