1 /* Definitions for Ada expressions
3 Copyright (C) 2020-2022 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
25 extern struct value
*ada_unop_neg (struct type
*expect_type
,
26 struct expression
*exp
,
27 enum noside noside
, enum exp_opcode op
,
29 extern struct value
*ada_atr_tag (struct type
*expect_type
,
30 struct expression
*exp
,
31 enum noside noside
, enum exp_opcode op
,
33 extern struct value
*ada_atr_size (struct type
*expect_type
,
34 struct expression
*exp
,
35 enum noside noside
, enum exp_opcode op
,
37 extern struct value
*ada_abs (struct type
*expect_type
,
38 struct expression
*exp
,
39 enum noside noside
, enum exp_opcode op
,
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
,
56 struct value
*low_bound_val
,
57 struct value
*high_bound_val
);
58 extern struct value
*ada_binop_in_bounds (struct expression
*exp
,
63 extern struct value
*ada_binop_minmax (struct type
*expect_type
,
64 struct expression
*exp
,
65 enum noside noside
, enum exp_opcode op
,
68 extern struct value
*ada_pos_atr (struct type
*expect_type
,
69 struct expression
*exp
,
70 enum noside noside
, enum exp_opcode op
,
72 extern struct value
*ada_val_atr (enum noside noside
, struct type
*type
,
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
);
82 /* The base class for Ada type resolution. Ada operations that want
83 to participate in resolution implement this interface. */
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
,
95 bool parse_completion
,
96 innermost_block_tracker
*tracker
,
97 struct type
*context_type
) = 0;
99 /* Possibly replace this object with some other expression object.
100 This is like 'resolve', but can return a replacement.
102 The default implementation calls 'resolve' and wraps this object
103 in a function call if that call returns true. OWNER is a
104 reference to the unique pointer that owns the 'this'; it can be
105 'move'd from to construct the replacement.
107 This should either return a new object, or OWNER -- never
110 virtual operation_up
replace (operation_up
&&owner
,
111 struct expression
*exp
,
113 bool parse_completion
,
114 innermost_block_tracker
*tracker
,
115 struct type
*context_type
);
118 /* In Ada, some generic operations must be wrapped with a handler that
119 handles some Ada-specific type conversions. */
120 class ada_wrapped_operation
121 : public tuple_holding_operation
<operation_up
>
125 using tuple_holding_operation::tuple_holding_operation
;
127 value
*evaluate (struct type
*expect_type
,
128 struct expression
*exp
,
129 enum noside noside
) override
;
131 enum exp_opcode
opcode () const override
132 { return std::get
<0> (m_storage
)->opcode (); }
135 /* An Ada string constant. */
136 class ada_string_operation
137 : public string_operation
141 using string_operation::string_operation
;
143 /* Return the underlying string. */
144 const char *get_name () const
146 return std::get
<0> (m_storage
).c_str ();
149 value
*evaluate (struct type
*expect_type
,
150 struct expression
*exp
,
151 enum noside noside
) override
;
154 /* The Ada TYPE'(EXP) construct. */
155 class ada_qual_operation
156 : public tuple_holding_operation
<operation_up
, struct type
*>
160 using tuple_holding_operation::tuple_holding_operation
;
162 value
*evaluate (struct type
*expect_type
,
163 struct expression
*exp
,
164 enum noside noside
) override
;
166 enum exp_opcode
opcode () const override
167 { return UNOP_QUAL
; }
170 /* Ternary in-range operator. */
171 class ada_ternop_range_operation
172 : public tuple_holding_operation
<operation_up
, operation_up
, operation_up
>
176 using tuple_holding_operation::tuple_holding_operation
;
178 value
*evaluate (struct type
*expect_type
,
179 struct expression
*exp
,
180 enum noside noside
) override
;
182 enum exp_opcode
opcode () const override
183 { return TERNOP_IN_RANGE
; }
186 using ada_neg_operation
= unop_operation
<UNOP_NEG
, ada_unop_neg
>;
187 using ada_atr_tag_operation
= unop_operation
<OP_ATR_TAG
, ada_atr_tag
>;
188 using ada_atr_size_operation
= unop_operation
<OP_ATR_SIZE
, ada_atr_size
>;
189 using ada_abs_operation
= unop_operation
<UNOP_ABS
, ada_abs
>;
190 using ada_pos_operation
= unop_operation
<OP_ATR_POS
, ada_pos_atr
>;
192 /* The in-range operation, given a type. */
193 class ada_unop_range_operation
194 : public tuple_holding_operation
<operation_up
, struct type
*>
198 using tuple_holding_operation::tuple_holding_operation
;
200 value
*evaluate (struct type
*expect_type
,
201 struct expression
*exp
,
202 enum noside noside
) override
204 value
*val
= std::get
<0> (m_storage
)->evaluate (nullptr, exp
, noside
);
205 return ada_unop_in_range (expect_type
, exp
, noside
, UNOP_IN_RANGE
,
206 val
, std::get
<1> (m_storage
));
209 enum exp_opcode
opcode () const override
210 { return UNOP_IN_RANGE
; }
213 /* The Ada + and - operators. */
214 class ada_binop_addsub_operation
215 : public tuple_holding_operation
<enum exp_opcode
, operation_up
, operation_up
>
219 using tuple_holding_operation::tuple_holding_operation
;
221 value
*evaluate (struct type
*expect_type
,
222 struct expression
*exp
,
223 enum noside noside
) override
;
225 enum exp_opcode
opcode () const override
226 { return std::get
<0> (m_storage
); }
229 using ada_binop_mul_operation
= binop_operation
<BINOP_MUL
, ada_mult_binop
>;
230 using ada_binop_div_operation
= binop_operation
<BINOP_DIV
, ada_mult_binop
>;
231 using ada_binop_rem_operation
= binop_operation
<BINOP_REM
, ada_mult_binop
>;
232 using ada_binop_mod_operation
= binop_operation
<BINOP_MOD
, ada_mult_binop
>;
234 using ada_binop_min_operation
= binop_operation
<BINOP_MIN
, ada_binop_minmax
>;
235 using ada_binop_max_operation
= binop_operation
<BINOP_MAX
, ada_binop_minmax
>;
237 using ada_binop_exp_operation
= binop_operation
<BINOP_EXP
, ada_binop_exp
>;
239 /* Implement the equal and not-equal operations for Ada. */
240 class ada_binop_equal_operation
241 : public tuple_holding_operation
<enum exp_opcode
, operation_up
, operation_up
>
245 using tuple_holding_operation::tuple_holding_operation
;
247 value
*evaluate (struct type
*expect_type
,
248 struct expression
*exp
,
249 enum noside noside
) override
251 value
*arg1
= std::get
<1> (m_storage
)->evaluate (nullptr, exp
, noside
);
252 value
*arg2
= std::get
<2> (m_storage
)->evaluate (value_type (arg1
),
254 return ada_equal_binop (expect_type
, exp
, noside
, std::get
<0> (m_storage
),
258 enum exp_opcode
opcode () const override
259 { return std::get
<0> (m_storage
); }
262 /* Bitwise operators for Ada. */
263 template<enum exp_opcode OP
>
264 class ada_bitwise_operation
265 : public maybe_constant_operation
<operation_up
, operation_up
>
269 using maybe_constant_operation::maybe_constant_operation
;
271 value
*evaluate (struct type
*expect_type
,
272 struct expression
*exp
,
273 enum noside noside
) override
275 value
*lhs
= std::get
<0> (m_storage
)->evaluate (nullptr, exp
, noside
);
276 value
*rhs
= std::get
<1> (m_storage
)->evaluate (nullptr, exp
, noside
);
277 value
*result
= eval_op_binary (expect_type
, exp
, noside
, OP
, lhs
, rhs
);
278 return value_cast (value_type (lhs
), result
);
281 enum exp_opcode
opcode () const override
285 using ada_bitwise_and_operation
= ada_bitwise_operation
<BINOP_BITWISE_AND
>;
286 using ada_bitwise_ior_operation
= ada_bitwise_operation
<BINOP_BITWISE_IOR
>;
287 using ada_bitwise_xor_operation
= ada_bitwise_operation
<BINOP_BITWISE_XOR
>;
289 /* Ada array- or string-slice operation. */
290 class ada_ternop_slice_operation
291 : public maybe_constant_operation
<operation_up
, operation_up
, operation_up
>,
292 public ada_resolvable
296 using maybe_constant_operation::maybe_constant_operation
;
298 value
*evaluate (struct type
*expect_type
,
299 struct expression
*exp
,
300 enum noside noside
) override
302 value
*array
= std::get
<0> (m_storage
)->evaluate (nullptr, exp
, noside
);
303 value
*low
= std::get
<1> (m_storage
)->evaluate (nullptr, exp
, noside
);
304 value
*high
= std::get
<2> (m_storage
)->evaluate (nullptr, exp
, noside
);
305 return ada_ternop_slice (exp
, noside
, array
, low
, high
);
308 enum exp_opcode
opcode () const override
309 { return TERNOP_SLICE
; }
311 bool resolve (struct expression
*exp
,
313 bool parse_completion
,
314 innermost_block_tracker
*tracker
,
315 struct type
*context_type
) override
;
318 /* Implement BINOP_IN_BOUNDS for Ada. */
319 class ada_binop_in_bounds_operation
320 : public maybe_constant_operation
<operation_up
, operation_up
, int>
324 using maybe_constant_operation::maybe_constant_operation
;
326 value
*evaluate (struct type
*expect_type
,
327 struct expression
*exp
,
328 enum noside noside
) override
330 value
*arg1
= std::get
<0> (m_storage
)->evaluate (nullptr, exp
, noside
);
331 value
*arg2
= std::get
<1> (m_storage
)->evaluate (nullptr, exp
, noside
);
332 return ada_binop_in_bounds (exp
, noside
, arg1
, arg2
,
333 std::get
<2> (m_storage
));
336 enum exp_opcode
opcode () const override
337 { return BINOP_IN_BOUNDS
; }
340 /* Implement several unary Ada OP_ATR_* operations. */
341 class ada_unop_atr_operation
342 : public maybe_constant_operation
<operation_up
, enum exp_opcode
, int>
346 using maybe_constant_operation::maybe_constant_operation
;
348 value
*evaluate (struct type
*expect_type
,
349 struct expression
*exp
,
350 enum noside noside
) override
;
352 enum exp_opcode
opcode () const override
353 { return std::get
<1> (m_storage
); }
356 /* Variant of var_value_operation for Ada. */
357 class ada_var_value_operation
358 : public var_value_operation
, public ada_resolvable
362 using var_value_operation::var_value_operation
;
364 value
*evaluate (struct type
*expect_type
,
365 struct expression
*exp
,
366 enum noside noside
) override
;
368 value
*evaluate_for_cast (struct type
*expect_type
,
369 struct expression
*exp
,
370 enum noside noside
) override
;
372 const block
*get_block () const
373 { return std::get
<0> (m_storage
).block
; }
375 bool resolve (struct expression
*exp
,
377 bool parse_completion
,
378 innermost_block_tracker
*tracker
,
379 struct type
*context_type
) override
;
383 using operation::do_generate_ax
;
386 /* Variant of var_msym_value_operation for Ada. */
387 class ada_var_msym_value_operation
388 : public var_msym_value_operation
392 using var_msym_value_operation::var_msym_value_operation
;
394 value
*evaluate_for_cast (struct type
*expect_type
,
395 struct expression
*exp
,
396 enum noside noside
) override
;
400 using operation::do_generate_ax
;
403 /* Implement the Ada 'val attribute. */
404 class ada_atr_val_operation
405 : public tuple_holding_operation
<struct type
*, operation_up
>
409 using tuple_holding_operation::tuple_holding_operation
;
411 value
*evaluate (struct type
*expect_type
,
412 struct expression
*exp
,
413 enum noside noside
) override
;
415 enum exp_opcode
opcode () const override
416 { return OP_ATR_VAL
; }
419 /* The indirection operator for Ada. */
420 class ada_unop_ind_operation
421 : public unop_ind_base_operation
425 using unop_ind_base_operation::unop_ind_base_operation
;
427 value
*evaluate (struct type
*expect_type
,
428 struct expression
*exp
,
429 enum noside noside
) override
;
432 /* Implement STRUCTOP_STRUCT for Ada. */
433 class ada_structop_operation
434 : public structop_base_operation
438 using structop_base_operation::structop_base_operation
;
440 value
*evaluate (struct type
*expect_type
,
441 struct expression
*exp
,
442 enum noside noside
) override
;
444 enum exp_opcode
opcode () const override
445 { return STRUCTOP_STRUCT
; }
447 /* Set the completion prefix. */
448 void set_prefix (std::string
&&prefix
)
450 m_prefix
= std::move (prefix
);
453 bool complete (struct expression
*exp
, completion_tracker
&tracker
) override
455 return structop_base_operation::complete (exp
, tracker
, m_prefix
.c_str ());
458 void dump (struct ui_file
*stream
, int depth
) const override
460 structop_base_operation::dump (stream
, depth
);
461 dump_for_expression (stream
, depth
+ 1, m_prefix
);
466 /* We may need to provide a prefix to field name completion. See
467 ada-exp.y:find_completion_bounds for details. */
468 std::string m_prefix
;
471 /* Function calls for Ada. */
472 class ada_funcall_operation
473 : public tuple_holding_operation
<operation_up
, std::vector
<operation_up
>>,
474 public ada_resolvable
478 using tuple_holding_operation::tuple_holding_operation
;
480 value
*evaluate (struct type
*expect_type
,
481 struct expression
*exp
,
482 enum noside noside
) override
;
484 bool resolve (struct expression
*exp
,
486 bool parse_completion
,
487 innermost_block_tracker
*tracker
,
488 struct type
*context_type
) override
;
490 enum exp_opcode
opcode () const override
491 { return OP_FUNCALL
; }
494 /* An Ada assignment operation. */
495 class ada_assign_operation
496 : public assign_operation
500 using assign_operation::assign_operation
;
502 value
*evaluate (struct type
*expect_type
,
503 struct expression
*exp
,
504 enum noside noside
) override
;
506 enum exp_opcode
opcode () const override
507 { return BINOP_ASSIGN
; }
510 /* This abstract class represents a single component in an Ada
511 aggregate assignment. */
516 /* Assign to LHS, which is part of CONTAINER. EXP is the expression
517 being evaluated. INDICES, LOW, and HIGH indicate which
518 sub-components have already been assigned; INDICES should be
519 updated by this call. */
520 virtual void assign (struct value
*container
,
521 struct value
*lhs
, struct expression
*exp
,
522 std::vector
<LONGEST
> &indices
,
523 LONGEST low
, LONGEST high
) = 0;
525 /* Same as operation::uses_objfile. */
526 virtual bool uses_objfile (struct objfile
*objfile
) = 0;
528 /* Same as operation::dump. */
529 virtual void dump (ui_file
*stream
, int depth
) = 0;
531 virtual ~ada_component () = default;
535 ada_component () = default;
536 DISABLE_COPY_AND_ASSIGN (ada_component
);
539 /* Unique pointer specialization for Ada assignment components. */
540 typedef std::unique_ptr
<ada_component
> ada_component_up
;
542 /* An operation that holds a single component. */
543 class ada_aggregate_operation
544 : public tuple_holding_operation
<ada_component_up
>
548 using tuple_holding_operation::tuple_holding_operation
;
550 /* Assuming that LHS represents an lvalue having a record or array
551 type, evaluate an assignment of this aggregate's value to LHS.
552 CONTAINER is an lvalue containing LHS (possibly LHS itself).
553 Does not modify the inferior's memory, nor does it modify the
554 contents of LHS (unless == CONTAINER). Returns the modified
557 value
*assign_aggregate (struct value
*container
,
559 struct expression
*exp
);
561 value
*evaluate (struct type
*expect_type
,
562 struct expression
*exp
,
563 enum noside noside
) override
565 error (_("Aggregates only allowed on the right of an assignment"));
568 enum exp_opcode
opcode () const override
569 { return OP_AGGREGATE
; }
572 /* A component holding a vector of other components to assign. */
573 class ada_aggregate_component
: public ada_component
577 explicit ada_aggregate_component (std::vector
<ada_component_up
> &&components
)
578 : m_components (std::move (components
))
582 void assign (struct value
*container
,
583 struct value
*lhs
, struct expression
*exp
,
584 std::vector
<LONGEST
> &indices
,
585 LONGEST low
, LONGEST high
) override
;
587 bool uses_objfile (struct objfile
*objfile
) override
;
589 void dump (ui_file
*stream
, int depth
) override
;
593 std::vector
<ada_component_up
> m_components
;
596 /* A component that assigns according to a provided index (which is
597 relative to the "low" value). */
598 class ada_positional_component
: public ada_component
602 ada_positional_component (int index
, operation_up
&&op
)
604 m_op (std::move (op
))
608 void assign (struct value
*container
,
609 struct value
*lhs
, struct expression
*exp
,
610 std::vector
<LONGEST
> &indices
,
611 LONGEST low
, LONGEST high
) override
;
613 bool uses_objfile (struct objfile
*objfile
) override
;
615 void dump (ui_file
*stream
, int depth
) override
;
623 /* A component which handles an "others" clause. */
624 class ada_others_component
: public ada_component
628 explicit ada_others_component (operation_up
&&op
)
629 : m_op (std::move (op
))
633 void assign (struct value
*container
,
634 struct value
*lhs
, struct expression
*exp
,
635 std::vector
<LONGEST
> &indices
,
636 LONGEST low
, LONGEST high
) override
;
638 bool uses_objfile (struct objfile
*objfile
) override
;
640 void dump (ui_file
*stream
, int depth
) override
;
647 /* An interface that represents an association that is used in
648 aggregate assignment. */
649 class ada_association
653 /* Like ada_component::assign, but takes an operation as a
654 parameter. The operation is evaluated and then assigned into LHS
655 according to the rules of the concrete implementation. */
656 virtual void assign (struct value
*container
,
658 struct expression
*exp
,
659 std::vector
<LONGEST
> &indices
,
660 LONGEST low
, LONGEST high
,
661 operation_up
&op
) = 0;
663 /* Same as operation::uses_objfile. */
664 virtual bool uses_objfile (struct objfile
*objfile
) = 0;
666 /* Same as operation::dump. */
667 virtual void dump (ui_file
*stream
, int depth
) = 0;
669 virtual ~ada_association () = default;
673 ada_association () = default;
674 DISABLE_COPY_AND_ASSIGN (ada_association
);
677 /* Unique pointer specialization for Ada assignment associations. */
678 typedef std::unique_ptr
<ada_association
> ada_association_up
;
680 /* A component that holds a vector of associations and an operation.
681 The operation is re-evaluated for each choice. */
682 class ada_choices_component
: public ada_component
686 explicit ada_choices_component (operation_up
&&op
)
687 : m_op (std::move (op
))
691 /* Set the vector of associations. This is done separately from the
692 constructor because it was simpler for the implementation of the
694 void set_associations (std::vector
<ada_association_up
> &&assoc
)
696 m_assocs
= std::move (assoc
);
699 void assign (struct value
*container
,
700 struct value
*lhs
, struct expression
*exp
,
701 std::vector
<LONGEST
> &indices
,
702 LONGEST low
, LONGEST high
) override
;
704 bool uses_objfile (struct objfile
*objfile
) override
;
706 void dump (ui_file
*stream
, int depth
) override
;
710 std::vector
<ada_association_up
> m_assocs
;
714 /* An association that uses a discrete range. */
715 class ada_discrete_range_association
: public ada_association
719 ada_discrete_range_association (operation_up
&&low
, operation_up
&&high
)
720 : m_low (std::move (low
)),
721 m_high (std::move (high
))
725 void assign (struct value
*container
,
726 struct value
*lhs
, struct expression
*exp
,
727 std::vector
<LONGEST
> &indices
,
728 LONGEST low
, LONGEST high
,
729 operation_up
&op
) override
;
731 bool uses_objfile (struct objfile
*objfile
) override
;
733 void dump (ui_file
*stream
, int depth
) override
;
741 /* An association that uses a name. The name may be an expression
742 that evaluates to an integer (for arrays), or an Ada string or
743 variable value operation. */
744 class ada_name_association
: public ada_association
748 explicit ada_name_association (operation_up val
)
749 : m_val (std::move (val
))
753 void assign (struct value
*container
,
754 struct value
*lhs
, struct expression
*exp
,
755 std::vector
<LONGEST
> &indices
,
756 LONGEST low
, LONGEST high
,
757 operation_up
&op
) override
;
759 bool uses_objfile (struct objfile
*objfile
) override
;
761 void dump (ui_file
*stream
, int depth
) override
;
768 /* A character constant expression. This is a separate operation so
769 that it can participate in resolution, so that TYPE'(CST) can
770 work correctly for enums with character enumerators. */
771 class ada_char_operation
: public long_const_operation
,
772 public ada_resolvable
776 using long_const_operation::long_const_operation
;
778 bool resolve (struct expression
*exp
,
780 bool parse_completion
,
781 innermost_block_tracker
*tracker
,
782 struct type
*context_type
) override
784 /* This should never be called, because this class also implements
786 gdb_assert_not_reached ("unexpected call");
789 operation_up
replace (operation_up
&&owner
,
790 struct expression
*exp
,
792 bool parse_completion
,
793 innermost_block_tracker
*tracker
,
794 struct type
*context_type
) override
;
796 value
*evaluate (struct type
*expect_type
,
797 struct expression
*exp
,
798 enum noside noside
) override
;
801 class ada_concat_operation
: public concat_operation
805 using concat_operation::concat_operation
;
807 value
*evaluate (struct type
*expect_type
,
808 struct expression
*exp
,
809 enum noside noside
) override
;
812 } /* namespace expr */
814 #endif /* ADA_EXP_H */